From 69d603e6fc3b343551260ca9c615affa98af8cee Mon Sep 17 00:00:00 2001 From: Spencer McIntyre Date: Thu, 2 May 2024 16:25:10 -0400 Subject: [PATCH] Switch to an enum option for the signing --- .../Attacking-AD-CS-ESC-Vulnerabilities.md | 1 - .../admin/ldap/shadow_credentials.md | 21 +++++---- .../ldap/vmware_vcenter_vmdir_auth_bypass.md | 23 +++++----- .../gather/ldap_esc_vulnerable_cert_finder.md | 1 - .../modules/auxiliary/gather/ldap_hashdump.md | 36 ++++++++-------- .../modules/auxiliary/gather/ldap_query.md | 20 ++++----- .../gather/vmware_vcenter_vmdir_ldap.md | 22 +++++----- lib/metasploit/framework/ldap/client.rb | 35 ++++++++------- lib/msf/core/exploit/remote/ldap.rb | 43 ++++++++++++------- lib/rex/proto/ldap/ldap_exception.rb | 6 +-- lib/rex/proto/sasl.rb | 28 ++++++------ 11 files changed, 120 insertions(+), 116 deletions(-) diff --git a/docs/metasploit-framework.wiki/ad-certificates/Attacking-AD-CS-ESC-Vulnerabilities.md b/docs/metasploit-framework.wiki/ad-certificates/Attacking-AD-CS-ESC-Vulnerabilities.md index 55e20da12943..80106fcdd804 100644 --- a/docs/metasploit-framework.wiki/ad-certificates/Attacking-AD-CS-ESC-Vulnerabilities.md +++ b/docs/metasploit-framework.wiki/ad-certificates/Attacking-AD-CS-ESC-Vulnerabilities.md @@ -196,7 +196,6 @@ Module options (auxiliary/gather/ldap_esc_vulnerable_cert_finder): DOMAIN no The domain to authenticate to PASSWORD no The password to authenticate with REPORT_NONENROLLABLE false yes Report nonenrollable certificate templates - REQUIRE_SIGNING true yes Use signed and encrypted LDAP RHOSTS yes The target host(s), see https://github.com/rapid7/metasploit -framework/wiki/Using-Metasploit RPORT 389 yes The target port diff --git a/documentation/modules/auxiliary/admin/ldap/shadow_credentials.md b/documentation/modules/auxiliary/admin/ldap/shadow_credentials.md index 216a4f038336..b8e789b2da7e 100755 --- a/documentation/modules/auxiliary/admin/ldap/shadow_credentials.md +++ b/documentation/modules/auxiliary/admin/ldap/shadow_credentials.md @@ -107,16 +107,15 @@ msf6 auxiliary(admin/ldap/shadow_credentials) > show options Module options (auxiliary/admin/ldap/shadow_credentials): - Name Current Setting Required Description - ---- --------------- -------- ----------- - DOMAIN no The domain to authenticate to - PASSWORD no The password to authenticate with - REQUIRE_SIGNING true yes Use signed and encrypted LDAP - RHOSTS yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html - RPORT 389 yes The target port - SSL false no Enable SSL on the LDAP connection - TARGET_USER yes The target to write to - USERNAME no The username to authenticate with + Name Current Setting Required Description + ---- --------------- -------- ----------- + DOMAIN no The domain to authenticate to + PASSWORD no The password to authenticate with + RHOSTS yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html + RPORT 389 yes The target port + SSL false no Enable SSL on the LDAP connection + TARGET_USER yes The target to write to + USERNAME no The username to authenticate with When ACTION is REMOVE: @@ -262,4 +261,4 @@ msf6 auxiliary(admin/ldap/shadow_credentials) > run rhost=20.92.148.129 username [*] Certificate stored at: /home/user/.msf4/loot/20240404122240_default_20.92.148.129_windows.ad.cs_785877.pfx [+] Successfully updated the msDS-KeyCredentialLink attribute; certificate with device ID 1107833b-0eb6-0477-a7c6-3590b326851a [*] Auxiliary module execution completed -``` \ No newline at end of file +``` diff --git a/documentation/modules/auxiliary/admin/ldap/vmware_vcenter_vmdir_auth_bypass.md b/documentation/modules/auxiliary/admin/ldap/vmware_vcenter_vmdir_auth_bypass.md index c9f37f8ba584..1a7201294bf7 100644 --- a/documentation/modules/auxiliary/admin/ldap/vmware_vcenter_vmdir_auth_bypass.md +++ b/documentation/modules/auxiliary/admin/ldap/vmware_vcenter_vmdir_auth_bypass.md @@ -60,18 +60,17 @@ msf5 auxiliary(admin/ldap/vmware_vcenter_vmdir_auth_bypass) > options Module options (auxiliary/admin/ldap/vmware_vcenter_vmdir_auth_bypass): - Name Current Setting Required Description - ---- --------------- -------- ----------- - BASE_DN no LDAP base DN if you already have it - DOMAIN no The domain to authenticate to - NEW_PASSWORD no Password of admin user to add - NEW_USERNAME no Username of admin user to add - PASSWORD no The password to authenticate with - REQUIRE_SIGNING true yes Use signed and encrypted LDAP - RHOSTS yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html - RPORT 636 yes The target port - SSL true no Enable SSL on the LDAP connection - USERNAME no The username to authenticate with + Name Current Setting Required Description + ---- --------------- -------- ----------- + BASE_DN no LDAP base DN if you already have it + DOMAIN no The domain to authenticate to + NEW_PASSWORD no Password of admin user to add + NEW_USERNAME no Username of admin user to add + PASSWORD no The password to authenticate with + RHOSTS yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html + RPORT 636 yes The target port + SSL true no Enable SSL on the LDAP connection + USERNAME no The username to authenticate with Auxiliary action: diff --git a/documentation/modules/auxiliary/gather/ldap_esc_vulnerable_cert_finder.md b/documentation/modules/auxiliary/gather/ldap_esc_vulnerable_cert_finder.md index 375535e3cf8c..517bb1b92493 100644 --- a/documentation/modules/auxiliary/gather/ldap_esc_vulnerable_cert_finder.md +++ b/documentation/modules/auxiliary/gather/ldap_esc_vulnerable_cert_finder.md @@ -116,7 +116,6 @@ Module options (auxiliary/gather/ldap_esc_vulnerable_cert_finder): BIND_DN DAFOREST\Administrator no The username to authenticate to LDAP server BIND_PW theAdmin123 no Password for the BIND_DN REPORT_NONENROLLABLE false yes Report nonenrollable certificate templates - REQUIRE_SIGNING true yes Use signed and encrypted LDAP RHOSTS 172.26.104.157 yes The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metasploit RPORT 389 yes The target port SSL false no Enable SSL on the LDAP connection diff --git a/documentation/modules/auxiliary/gather/ldap_hashdump.md b/documentation/modules/auxiliary/gather/ldap_hashdump.md index bbd9ec23c8a1..a0821969a10a 100644 --- a/documentation/modules/auxiliary/gather/ldap_hashdump.md +++ b/documentation/modules/auxiliary/gather/ldap_hashdump.md @@ -28,27 +28,25 @@ msf5 auxiliary(gather/ldap_hashdump) > options Module options (auxiliary/gather/ldap_hashdump): - Name Current Setting Required Description - ---- --------------- -------- ----------- - BASE_DN no LDAP base DN if you already have it - DOMAIN no The domain to authenticate to - MAX_LOOT no Maximum number of LDAP entries to loot - PASSWORD no The password to authenticate with - PASS_ATTR userPassword, sambantpassword, sambalmpassword, mailu yes LDAP attribute, that contains password hashes - serpassword, password, pwdhistory, passwordhistory, c - learpassword - READ_TIMEOUT 600 no LDAP read timeout in seconds - REQUIRE_SIGNING true yes Use signed and encrypted LDAP - RHOSTS 127.0.0.1 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.ht - ml - RPORT 1389 yes The target port - SSL true no Enable SSL on the LDAP connection - THREADS 1 yes The number of concurrent threads (max one per host) - USERNAME no The username to authenticate with - USER_ATTR dn no LDAP attribute(s), that contains username + Name Current Setting Required Description + ---- --------------- -------- ----------- + BASE_DN no LDAP base DN if you already have it] + DOMAIN no The domain to authenticate to + MAX_LOOT no Maximum number of LDAP entries to loot + PASSWORD no The password to authenticate with + PASS_ATTR userPassword, sambantpassword, sambalmpassword, mailu yes LDAP attribute, that contains password hashes + serpassword, password, pwdhistory, passwordhistory, c + learpassword + READ_TIMEOUT 600 no LDAP read timeout in seconds + RHOSTS 127.0.0.1 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.h + tml + RPORT 1389 yes The target port + SSL true no Enable SSL on the LDAP connection + THREADS 1 yes The number of concurrent threads (max one per host) + USERNAME no The username to authenticate with + USER_ATTR dn no LDAP attribute(s), that contains username Auxiliary action: - Name Description ---- ----------- Dump Dump all LDAP data diff --git a/documentation/modules/auxiliary/gather/ldap_query.md b/documentation/modules/auxiliary/gather/ldap_query.md index 90b1e9443c36..c7cd1d122770 100644 --- a/documentation/modules/auxiliary/gather/ldap_query.md +++ b/documentation/modules/auxiliary/gather/ldap_query.md @@ -215,16 +215,15 @@ msf6 auxiliary(gather/ldap_query) > show options Module options (auxiliary/gather/ldap_query): Name Current Setting Required Description - ---- --------------- -------- ----------- - BASE_DN no LDAP base DN if you already have it - DOMAIN no The domain to authenticate to - OUTPUT_FORMAT table yes The output format to use (Accepted: csv, table, json) - PASSWORD thePassword123 no The password to authenticate with - REQUIRE_SIGNING true yes Use signed and encrypted LDAP - RHOSTS 172.27.51.83 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html - RPORT 389 yes The target port - SSL false no Enable SSL on the LDAP connection - USERNAME normal@daforest.com no The username to authenticate with + ---- --------------- -------- ----------- + BASE_DN no LDAP base DN if you already have it + DOMAIN no The domain to authenticate to + OUTPUT_FORMAT table yes The output format to use (Accepted: csv, table, json) + PASSWORD thePassword123 no The password to authenticate with + RHOSTS 172.27.51.83 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html + RPORT 389 yes The target port + SSL false no Enable SSL on the LDAP connection + USERNAME normal@daforest.com no The username to authenticate with When ACTION is RUN_QUERY_FILE: @@ -242,7 +241,6 @@ Module options (auxiliary/gather/ldap_query): QUERY_FILTER no Filter to send to the target LDAP server to perform the query Auxiliary action: - Name Description ---- ----------- RUN_QUERY_FILE Execute a custom set of LDAP queries from the JSON or YAML file specified by QUERY_FILE. diff --git a/documentation/modules/auxiliary/gather/vmware_vcenter_vmdir_ldap.md b/documentation/modules/auxiliary/gather/vmware_vcenter_vmdir_ldap.md index ada0bd7bb932..538a3bcf7b78 100644 --- a/documentation/modules/auxiliary/gather/vmware_vcenter_vmdir_ldap.md +++ b/documentation/modules/auxiliary/gather/vmware_vcenter_vmdir_ldap.md @@ -39,18 +39,16 @@ If you already have the LDAP base DN, you may set it in this option. msf5 > use auxiliary/gather/vmware_vcenter_vmdir_ldap msf5 auxiliary(gather/vmware_vcenter_vmdir_ldap) > options -Module options (auxiliary/gather/vmware_vcenter_vmdir_ldap): - - Name Current Setting Required Description - ---- --------------- -------- ----------- - BASE_DN no LDAP base DN if you already have it - DOMAIN no The domain to authenticate to - PASSWORD no The password to authenticate with - REQUIRE_SIGNING true yes Use signed and encrypted LDAP - RHOSTS yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html - RPORT 636 yes The target port - SSL true no Enable SSL on the LDAP connection - USERNAME no The username to authenticate with + Name Current Setting Required Description + ---- --------------- -------- ----------- + BASE_DN no LDAP base DN if you already have it + DOMAIN no The domain to authenticate to + PASSWORD no The password to authenticate with + RHOSTS yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html + RPORT 636 yes The target port + SSL true no Enable SSL on the LDAP connection + USERNAME no The username to authenticate with + Auxiliary action: diff --git a/lib/metasploit/framework/ldap/client.rb b/lib/metasploit/framework/ldap/client.rb index 740334ee788b..c7f53eea789b 100644 --- a/lib/metasploit/framework/ldap/client.rb +++ b/lib/metasploit/framework/ldap/client.rb @@ -127,18 +127,16 @@ def ldap_connect_opts(rhost, rport, connect_timeout, ssl: true, opts: {}) case opts[:ldap_auth] when Msf::Exploit::Remote::AuthOption::SCHANNEL - raise Msf::ValidationError, 'The SSL option must be enabled when using SCHANNEL authentication.' unless ssl - - connect_opts.merge!(ldap_auth_opts_schannel(opts)) + connect_opts.merge!(ldap_auth_opts_schannel(opts, ssl)) when Msf::Exploit::Remote::AuthOption::KERBEROS - connect_opts.merge!(ldap_auth_opts_kerberos(opts)) + connect_opts.merge!(ldap_auth_opts_kerberos(opts, ssl)) when Msf::Exploit::Remote::AuthOption::NTLM - connect_opts.merge!(ldap_auth_opts_ntlm(opts)) + connect_opts.merge!(ldap_auth_opts_ntlm(opts, ssl)) when Msf::Exploit::Remote::AuthOption::PLAINTEXT connect_opts.merge!(ldap_auth_opts_plaintext(opts)) when Msf::Exploit::Remote::AuthOption::AUTO if opts[:username].present? && opts[:domain].present? - connect_opts.merge!(ldap_auth_opts_ntlm(opts)) + connect_opts.merge!(ldap_auth_opts_ntlm(opts, ssl)) elsif opts[:username].present? connect_opts.merge!(ldap_auth_opts_plaintext(opts)) end @@ -149,15 +147,15 @@ def ldap_connect_opts(rhost, rport, connect_timeout, ssl: true, opts: {}) private - def ldap_auth_opts_kerberos(opts) + def ldap_auth_opts_kerberos(opts, ssl) auth_opts = {} - raise Msf::ValidationError, 'The Ldap::Rhostname option is required when using Kerberos authentication.' if opts[:ldap_rhostname].blank? + raise Msf::ValidationError, 'The LDAP::Rhostname option is required when using Kerberos authentication.' if opts[:ldap_rhostname].blank? raise Msf::ValidationError, 'The DOMAIN option is required when using Kerberos authentication.' if opts[:domain].blank? offered_etypes = Msf::Exploit::Remote::AuthOption.as_default_offered_etypes(opts[:ldap_krb_offered_enc_types]) raise Msf::ValidationError, 'At least one encryption type is required when using Kerberos authentication.' if offered_etypes.empty? - use_gss_checksum = opts[:should_encrypt] + sign_and_seal = opts.fetch(:sign_and_seal, !ssl) kerberos_authenticator = Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::LDAP.new( host: opts[:domain_controller_rhost].blank? ? nil : opts[:domain_controller_rhost], hostname: opts[:ldap_rhostname], @@ -170,7 +168,7 @@ def ldap_auth_opts_kerberos(opts) ticket_storage: opts[:kerberos_ticket_storage], offered_etypes: offered_etypes, mutual_auth: true, - use_gss_checksum: use_gss_checksum + use_gss_checksum: sign_and_seal ) encryptor = SpnegoKerberosEncryptor.new(kerberos_authenticator) @@ -184,14 +182,14 @@ def ldap_auth_opts_kerberos(opts) challenge_response: true } - if opts[:should_encrypt] + if sign_and_seal auth_opts[:auth][:auth_context_setup] = encryptor.method(:kerberos_setup) end auth_opts end - def ldap_auth_opts_ntlm(opts) + def ldap_auth_opts_ntlm(opts, ssl) auth_opts = {} flags = RubySMB::NTLM::NEGOTIATE_FLAGS[:UNICODE] | RubySMB::NTLM::NEGOTIATE_FLAGS[:REQUEST_TARGET] | @@ -202,7 +200,8 @@ def ldap_auth_opts_ntlm(opts) RubySMB::NTLM::NEGOTIATE_FLAGS[:TARGET_INFO] | RubySMB::NTLM::NEGOTIATE_FLAGS[:VERSION_INFO] - if opts[:should_encrypt] + sign_and_seal = opts.fetch(:sign_and_seal, !ssl) + if sign_and_seal flags = flags | RubySMB::NTLM::NEGOTIATE_FLAGS[:SIGN] | RubySMB::NTLM::NEGOTIATE_FLAGS[:SEAL] | @@ -234,7 +233,7 @@ def ldap_auth_opts_ntlm(opts) challenge_response: negotiate } - if opts[:should_encrypt] + if sign_and_seal auth_opts[:auth][:auth_context_setup] = encryptor.method(:ntlm_setup) end @@ -243,6 +242,8 @@ def ldap_auth_opts_ntlm(opts) def ldap_auth_opts_plaintext(opts) auth_opts = {} + raise Msf::ValidationError, 'Can not sign and seal when using Plaintext authentication.' if opts.fetch(:sign_and_seal, false) + auth_opts[:auth] = { method: :simple, username: opts[:username], @@ -251,10 +252,12 @@ def ldap_auth_opts_plaintext(opts) auth_opts end - def ldap_auth_opts_schannel(opts) + def ldap_auth_opts_schannel(opts, ssl) auth_opts = {} pfx_path = opts[:ldap_cert_file] - raise Msf::ValidationError, 'The LDAP::CertFile option is required when using SCHANNEL authentication.' if pfx_path.blank? + raise Msf::ValidationError, 'The SSL option must be enabled when using Schannel authentication.' unless ssl + raise Msf::ValidationError, 'The LDAP::CertFile option is required when using Schannel authentication.' if pfx_path.blank? + raise Msf::ValidationError, 'Can not sign and seal when using Schannel authentication.' if opts.fetch(:sign_and_seal, false) unless ::File.file?(pfx_path) && ::File.readable?(pfx_path) raise Msf::ValidationError, 'Failed to load the PFX certificate file. The path was not a readable file.' diff --git a/lib/msf/core/exploit/remote/ldap.rb b/lib/msf/core/exploit/remote/ldap.rb index 702402e67624..7aa94dbc0d93 100644 --- a/lib/msf/core/exploit/remote/ldap.rb +++ b/lib/msf/core/exploit/remote/ldap.rb @@ -32,8 +32,7 @@ def initialize(info = {}) OptBool.new('SSL', [false, 'Enable SSL on the LDAP connection', false]), Msf::OptString.new('DOMAIN', [false, 'The domain to authenticate to']), Msf::OptString.new('USERNAME', [false, 'The username to authenticate with'], aliases: ['BIND_DN']), - Msf::OptString.new('PASSWORD', [false, 'The password to authenticate with'], aliases: ['BIND_PW']), - OptBool.new('REQUIRE_SIGNING', [true, 'Use signed and encrypted LDAP', true]) + Msf::OptString.new('PASSWORD', [false, 'The password to authenticate with'], aliases: ['BIND_PW']) ]) register_advanced_options( @@ -42,7 +41,8 @@ def initialize(info = {}) *kerberos_storage_options(protocol: 'LDAP'), *kerberos_auth_options(protocol: 'LDAP', auth_methods: Msf::Exploit::Remote::AuthOption::LDAP_OPTIONS), Msf::OptPath.new('LDAP::CertFile', [false, 'The path to the PKCS12 (.pfx) certificate file to authenticate with'], conditions: ['LDAP::Auth', '==', Msf::Exploit::Remote::AuthOption::SCHANNEL]), - OptFloat.new('LDAP::ConnectTimeout', [true, 'Timeout for LDAP connect', 10.0]) + OptFloat.new('LDAP::ConnectTimeout', [true, 'Timeout for LDAP connect', 10.0]), + OptEnum.new('LDAP::Signing', [true, 'Use signed and sealed (encrypted) LDAP', 'auto', %w[ disabled auto required ]]) ] ) end @@ -80,26 +80,37 @@ def get_connect_opts password: datastore['PASSWORD'], domain: datastore['DOMAIN'], domain_controller_rhost: datastore['DomainControllerRhost'], - should_encrypt: datastore['REQUIRE_SIGNING'], ldap_auth: datastore['LDAP::Auth'], ldap_cert_file: datastore['LDAP::CertFile'], - ldap_rhostname: datastore['Ldap::Rhostname'], - ldap_krb_offered_enc_types: datastore['Ldap::KrbOfferedEncryptionTypes'], - ldap_krb5_cname: datastore['Ldap::Krb5Ccname'], + ldap_rhostname: datastore['LDAP::Rhostname'], + ldap_krb_offered_enc_types: datastore['LDAP::KrbOfferedEncryptionTypes'], + ldap_krb5_cname: datastore['LDAP::Krb5Ccname'], proxies: datastore['Proxies'], framework_module: self } + case datastore['LDAP::Signing'] + when 'required' + opts[:sign_and_seal] = true + when 'disabled' + opts[:sign_and_seal] = false + end - result = ldap_connect_opts(rhost, rport, datastore['LDAP::ConnectTimeout'], ssl: datastore['SSL'], opts: opts) + begin + result = ldap_connect_opts(rhost, rport, datastore['LDAP::ConnectTimeout'], ssl: datastore['SSL'], opts: opts) + rescue Msf::ValidationError => e + fail_with(Msf::Module::Failure::BadConfig, e.message) + end # Now that the options have been resolved (including auto possibly resolving to NTLM), check whether this is a valid config - if result[:auth] && - result[:auth][:method] == :sasl && - result[:auth][:mechanism] == 'GSS-SPNEGO' && - datastore['SSL'] && - datastore['REQUIRE_SIGNING'] - # Domain Controllers don't seem to support signing and connection over SSL. Gotta pick one or the other. - fail_with(Msf::Module::Failure::BadConfig, 'SSL not supported with signing. Set either SSL or REQUIRE_SIGNING, but not both.') + if result[:auth] && datastore['LDAP::Signing'] == 'required' + unless (result[:auth][:method] == :sasl && result[:auth][:mechanism] == 'GSS-SPNEGO') + fail_with(Msf::Module::Failure::BadConfig, 'The authentication configuration does not support signing. Change either LDAP::Auth or LDAP::Signing.') + end + + if result[:encryption] + # Domain Controllers don't seem to support signing and connection over SSL. Gotta pick one or the other. + fail_with(Msf::Module::Failure::BadConfig, 'SSL not supported with signing. Change either SSL or LDAP::Signing.') + end end result @@ -257,7 +268,7 @@ def validate_bind_success!(ldap) fail_with(Msf::Module::Failure::NoTarget, 'Target does not support the simple authentication mechanism!') when 8 signing_statement = '' - signing_statement = 'May require LDAP signing to be enabled (`set REQUIRE_SIGNING true`). ' unless datastore['REQUIRE_SIGNING'] + signing_statement = 'May require LDAP signing to be enabled (`set LDAP::EnableSigning true`). ' unless datastore['LDAP::EnableSigning'] fail_with(Msf::Module::Failure::NoTarget, "Server requires a stronger form of authentication! #{signing_statement}The error was: #{bind_result[:error_message].strip}") when 14 diff --git a/lib/rex/proto/ldap/ldap_exception.rb b/lib/rex/proto/ldap/ldap_exception.rb index 3271ed373665..726521ced811 100755 --- a/lib/rex/proto/ldap/ldap_exception.rb +++ b/lib/rex/proto/ldap/ldap_exception.rb @@ -1,4 +1,4 @@ module Rex::Proto::LDAP - class LdapException < RuntimeError - end -end \ No newline at end of file + class LdapException < RuntimeError + end +end diff --git a/lib/rex/proto/sasl.rb b/lib/rex/proto/sasl.rb index 961d0b8dc3d2..6c0f8158d450 100755 --- a/lib/rex/proto/sasl.rb +++ b/lib/rex/proto/sasl.rb @@ -1,18 +1,18 @@ module Rex::Proto::Sasl - # Wrap the data in a SASL structure, per RFC 4422 (basically just prepends a big-endian encoded 32-bit integer representing the length) - def wrap_sasl(data) - length = [data.length].pack('N') + # Wrap the data in a SASL structure, per RFC 4422 (basically just prepends a big-endian encoded 32-bit integer representing the length) + def wrap_sasl(data) + length = [data.length].pack('N') - length + data - end - - # Unwraps the data from a SASL structure, per RFC 4422 - def unwrap_sasl(data) - length = data[0,4].unpack('N')[0] - if length != data.length + 4 - raise ArgumentError.new('Invalid SASL structure') - end + length + data + end - data[4,length] + # Unwraps the data from a SASL structure, per RFC 4422 + def unwrap_sasl(data) + length = data[0,4].unpack('N')[0] + if length != data.length + 4 + raise ArgumentError.new('Invalid SASL structure') end -end \ No newline at end of file + + data[4,length] + end +end