librex 0.0.12 → 0.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. data/README.markdown +1 -1
  2. data/Rakefile +1 -1
  3. data/lib/rex/io/stream.rb +1 -1
  4. data/lib/rex/parser/nmap_xml.rb +4 -1
  5. data/lib/rex/post/meterpreter/extensions/stdapi/railgun.rb.ts.rb +6 -0
  6. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/api_constants.rb.ut.rb +31 -0
  7. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/buffer_item.rb +47 -0
  8. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/buffer_item.rb.ut.rb +36 -0
  9. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/{model.rb → dll.rb} +4 -226
  10. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_function.rb +100 -0
  11. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_function.rb.ut.rb +42 -0
  12. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_helper.rb +148 -0
  13. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll_helper.rb.ut.rb +127 -0
  14. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/multicall.rb +2 -1
  15. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb +3 -2
  16. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb +1 -1
  17. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/win_const_manager.rb +75 -0
  18. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/win_const_manager.rb.ut.rb +103 -0
  19. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +44 -0
  20. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb +2 -2
  21. data/lib/rex/proto/dhcp/server.rb +7 -6
  22. data/lib/rex/proto/ntlm/utils.rb +505 -100
  23. data/lib/rex/proto/rfb/cipher.rb +6 -0
  24. data/lib/rex/proto/smb/client.rb +40 -332
  25. data/lib/rex/proto/smb/simpleclient.rb +3 -1
  26. data/lib/rex/proto/smb/utils.rb +0 -4
  27. metadata +14 -4
@@ -44,6 +44,9 @@ class Cipher
44
44
  def self.encrypt(plain, password)
45
45
  key = self.mangle_password(password)
46
46
 
47
+ # pad the plain to 16 chars
48
+ plain << ("\x00" * (16 - plain.length)) if plain.length < 16
49
+
47
50
  # VNC auth does two 8-byte blocks individually instead supporting some block mode
48
51
  cipher = ''
49
52
  2.times { |x|
@@ -63,6 +66,9 @@ class Cipher
63
66
  def self.decrypt(cipher, password = "\x17\x52\x6b\x06\x23\x4e\x58\x07")
64
67
  key = self.mangle_password(password)
65
68
 
69
+ # pad the cipher text to 9 bytes
70
+ cipher << ("\x00" * (9 - cipher.length)) if cipher.length < 9
71
+
66
72
  # NOTE: This only does one 8 byte block
67
73
  plain = ''
68
74
  c = OpenSSL::Cipher::Cipher.new('des')
@@ -58,6 +58,9 @@ NTLM_UTILS = Rex::Proto::NTLM::Utils
58
58
  self.signing_key = ''
59
59
  self.require_signing = false
60
60
 
61
+ #Misc
62
+ self.spnopt = {}
63
+
61
64
  end
62
65
 
63
66
  # Read a SMB packet from the socket
@@ -654,7 +657,7 @@ NTLM_UTILS = Rex::Proto::NTLM::Utils
654
657
  self.require_signing = false if self.require_signing
655
658
 
656
659
 
657
- if UTILS.is_pass_ntlm_hash?(pass)
660
+ if NTLM_UTILS.is_pass_ntlm_hash?(pass)
658
661
  arglm = {
659
662
  :lm_hash => [ pass.upcase()[0,32] ].pack('H32'),
660
663
  :challenge => self.challenge_key
@@ -720,7 +723,7 @@ NTLM_UTILS = Rex::Proto::NTLM::Utils
720
723
  # Authenticate without ntlmssp with a precomputed hash pair
721
724
  def session_setup_no_ntlmssp_prehash(user, domain, hash_lm, hash_nt, do_recv = true)
722
725
 
723
- raise XCEPT::NTLM2MissingChallenge if self.require_signing
726
+ #raise XCEPT::NTLM2MissingChallenge if self.require_signing
724
727
 
725
728
  data = ''
726
729
  data << hash_lm
@@ -769,32 +772,17 @@ NTLM_UTILS = Rex::Proto::NTLM::Utils
769
772
 
770
773
  # Authenticate using extended security negotiation
771
774
  def session_setup_with_ntlmssp(user = '', pass = '', domain = '', name = nil, do_recv = true)
772
-
773
- if require_signing
774
- ntlmssp_flags = 0xe2088215
775
- else
776
-
777
- ntlmssp_flags = 0xa2080205
778
- end
779
-
780
- if self.usentlm2_session
781
- if self.use_ntlmv2
782
- #set Negotiate Target Info
783
- ntlmssp_flags |= NTLM_CONST::NEGOTIATE_TARGET_INFO
784
- end
785
775
 
786
- else
787
- #remove the ntlm2_session flag
788
- ntlmssp_flags &= 0xfff7ffff
789
- #set lanmanflag only when lm and ntlm are sent
790
- if self.send_lm
791
- ntlmssp_flags |= NTLM_CONST::NEGOTIATE_LMKEY if self.use_lanman_key
792
- end
793
- end
794
-
795
- #we can also downgrade ntlm2_session when we send only lmv1
796
- ntlmssp_flags &= 0xfff7ffff if self.usentlm2_session && (not self.use_ntlmv2) && (not self.send_ntlm)
776
+ ntlm_options = {
777
+ :signing => self.require_signing,
778
+ :usentlm2_session => self.usentlm2_session,
779
+ :use_ntlmv2 => self.use_ntlmv2,
780
+ :send_lm => self.send_lm,
781
+ :send_ntlm => self.send_ntlm,
782
+ :use_lanman_key => self.use_lanman_key
783
+ }
797
784
 
785
+ ntlmssp_flags = NTLM_UTILS.make_ntlm_flags(ntlm_options)
798
786
 
799
787
  if (name == nil)
800
788
  name = Rex::Text.rand_text_alphanumeric(16)
@@ -861,315 +849,33 @@ NTLM_UTILS = Rex::Proto::NTLM::Utils
861
849
  # Save the temporary UserID for use in the next request
862
850
  temp_user_id = ack['Payload']['SMB'].v['UserID']
863
851
 
864
- # Extract the NTLM challenge key the lazy way
865
- cidx = blob.index("NTLMSSP\x00\x02\x00\x00\x00")
866
-
867
- if (cidx == -1)
868
- raise XCEPT::NTLM2MissingChallenge
869
- end
870
-
871
- # Store the challenge key
872
- self.challenge_key = blob[cidx + 24, 8]
873
-
874
- # Extract the address list from the blob
875
- alist_len,alist_mlen,alist_off = blob[cidx + 40, 8].unpack("vvV")
876
- alist_buf = blob[cidx + alist_off, alist_len]
877
- chall_MsvAvTimestamp = nil
878
- while(alist_buf.length > 0)
879
- atype, alen = alist_buf.slice!(0,4).unpack('vv')
880
- break if atype == 0x00
881
- addr = alist_buf.slice!(0, alen)
882
- case atype
883
- when 1
884
- #netbios name
885
- self.default_name = addr.gsub("\x00", '')
886
- when 2
887
- #netbios domain
888
- self.default_domain = addr.gsub("\x00", '')
889
- when 3
890
- #dns name
891
- self.dns_host_name = addr.gsub("\x00", '')
892
- when 4
893
- #dns domain
894
- self.dns_domain_name = addr.gsub("\x00", '')
895
- when 5
896
- #The FQDN of the forest.
897
- when 6
898
- #A 32-bit value indicating server or client configuration
899
- when 7
900
- #Client time
901
- chall_MsvAvTimestamp = addr
902
- when 8
903
- #A Restriction_Encoding structure
904
- when 9
905
- #The SPN of the target server.
906
- when 10
907
- #A channel bindings hash.
908
- end
909
- end
910
-
911
- #calculate the lm/ntlm response
912
- resp_lm = "\x00" * 24
913
- resp_ntlm = "\x00" * 24
914
-
915
- client_challenge = Rex::Text.rand_text(8)
916
- ntlm_cli_challenge = ''
917
- if self.send_ntlm #should be default
918
- if self.usentlm2_session
919
-
920
- if self.use_ntlmv2
921
- # This is only a partial implementation, in some situation recent servers may send STATUS_INVALID_PARAMETER
922
- # answer must then be somewhere in [MS-NLMP].pdf around 3.1.5.2.1 :-/
923
- ntlm_cli_challenge = NTLM_UTILS::make_ntlmv2_clientchallenge(default_domain, default_name, dns_domain_name,
924
- dns_host_name,client_challenge , chall_MsvAvTimestamp)
925
- if UTILS.is_pass_ntlm_hash?(pass)
926
- argntlm = {
927
- :ntlmv2_hash => NTLM_CRYPT::ntlmv2_hash(
928
- user,
929
- [ pass.upcase()[33,65] ].pack('H32'),
930
- domain,{:pass_is_hash => true}
931
- ),
932
- :challenge => self.challenge_key
933
- }
934
- else
935
- argntlm = {
936
- :ntlmv2_hash => NTLM_CRYPT::ntlmv2_hash(user, pass, domain),
937
- :challenge => self.challenge_key
938
- }
939
- end
940
-
941
- optntlm = { :nt_client_challenge => ntlm_cli_challenge}
942
- ntlmv2_response = NTLM_CRYPT::ntlmv2_response(argntlm,optntlm)
943
- resp_ntlm = ntlmv2_response
944
-
945
- if self.send_lm
946
- if UTILS.is_pass_ntlm_hash?(pass)
947
- arglm = {
948
- :ntlmv2_hash => NTLM_CRYPT::ntlmv2_hash(
949
- user,
950
- [ pass.upcase()[33,65] ].pack('H32'),
951
- domain,{:pass_is_hash => true}
952
- ),
953
- :challenge => self.challenge_key
954
- }
955
- else
956
- arglm = {
957
- :ntlmv2_hash => NTLM_CRYPT::ntlmv2_hash(user,pass, domain),
958
- :challenge => self.challenge_key
959
- }
960
- end
961
-
962
- optlm = { :client_challenge => client_challenge }
963
- resp_lm = NTLM_CRYPT::lmv2_response(arglm, optlm)
964
- else
965
- resp_lm = "\x00" * 24
966
- end
967
-
968
- else # ntlm2_session
969
- if UTILS.is_pass_ntlm_hash?(pass)
970
- argntlm = {
971
- :ntlm_hash => [ pass.upcase()[33,65] ].pack('H32'),
972
- :challenge => self.challenge_key
973
- }
974
- else
975
- argntlm = {
976
- :ntlm_hash => NTLM_CRYPT::ntlm_hash(pass),
977
- :challenge => self.challenge_key
978
- }
979
- end
980
-
981
- optntlm = { :client_challenge => client_challenge}
982
- resp_ntlm = NTLM_CRYPT::ntlm2_session(argntlm,optntlm).join[24,24]
983
-
984
- # Generate the fake LANMAN hash
985
- resp_lm = client_challenge + ("\x00" * 16)
986
- end
987
-
988
- else # we use lmv1/ntlmv1
989
- if UTILS.is_pass_ntlm_hash?(pass)
990
- argntlm = {
991
- :ntlm_hash => [ pass.upcase()[33,65] ].pack('H32'),
992
- :challenge => self.challenge_key
993
- }
994
- else
995
- argntlm = {
996
- :ntlm_hash => NTLM_CRYPT::ntlm_hash(pass),
997
- :challenge => self.challenge_key
998
- }
999
- end
1000
-
1001
- resp_ntlm = NTLM_CRYPT::ntlm_response(argntlm)
1002
- if self.send_lm
1003
- if UTILS.is_pass_ntlm_hash?(pass)
1004
- arglm = {
1005
- :lm_hash => [ pass.upcase()[0,32] ].pack('H32'),
1006
- :challenge => self.challenge_key
1007
- }
1008
- else
1009
- arglm = {
1010
- :lm_hash => NTLM_CRYPT::lm_hash(pass),
1011
- :challenge => self.challenge_key
1012
- }
1013
- end
1014
- resp_lm = NTLM_CRYPT::lm_response(arglm)
1015
- else
1016
- #when windows does not send lm in ntlmv1 type response,
1017
- # it gives lm response the same value as ntlm response
1018
- resp_lm = resp_ntlm
1019
- end
1020
- end
1021
- else #send_ntlm = false
1022
- #lmv2
1023
- if self.usentlm2_session && self.use_ntlmv2
1024
- if UTILS.is_pass_ntlm_hash?(pass)
1025
- arglm = {
1026
- :ntlmv2_hash => NTLM_CRYPT::ntlmv2_hash(
1027
- user,
1028
- [ pass.upcase()[33,65] ].pack('H32'),
1029
- domain,{:pass_is_hash => true}
1030
- ),
1031
- :challenge => self.challenge_key
1032
- }
1033
- else
1034
- arglm = {
1035
- :ntlmv2_hash => NTLM_CRYPT::ntlmv2_hash(user,pass, domain),
1036
- :challenge => self.challenge_key
1037
- }
1038
- end
1039
- optlm = { :client_challenge => client_challenge }
1040
- resp_lm = NTLM_CRYPT::lmv2_response(arglm, optlm)
1041
- else
1042
- if UTILS.is_pass_ntlm_hash?(pass)
1043
- arglm = {
1044
- :lm_hash => [ pass.upcase()[0,32] ].pack('H32'),
1045
- :challenge => self.challenge_key
1046
- }
1047
- else
1048
- arglm = {
1049
- :lm_hash => NTLM_CRYPT::lm_hash(pass),
1050
- :challenge => self.challenge_key
1051
- }
1052
- end
1053
- resp_lm = NTLM_CRYPT::lm_response(arglm)
1054
- end
1055
- resp_ntlm = ""
1056
- end
1057
-
1058
-
1059
- # Create the sessionkey (aka signing key, aka mackey) and encrypted session key
1060
- # Server will decide for key_size and key_exchange
852
+ # Get default data
853
+ blob_data = NTLM_UTILS.parse_ntlm_type_2_blob(blob)
854
+ self.challenge_key = blob_data[:challenge_key]
855
+ server_ntlmssp_flags = blob_data[:server_ntlmssp_flags] #else should raise an error
856
+ #netbios name
857
+ self.default_name = blob_data[:default_name] || ''
858
+ #netbios domain
859
+ self.default_domain = blob_data[:default_domain] || ''
860
+ #dns name
861
+ self.dns_host_name = blob_data[:dns_host_name] || ''
862
+ #dns domain
863
+ self.dns_domain_name = blob_data[:dns_domain_name] || ''
864
+ #Client time
865
+ chall_MsvAvTimestamp = blob_data[:chall_MsvAvTimestamp] || ''
866
+
867
+
868
+ resp_lm, resp_ntlm, client_challenge, ntlm_cli_challenge = NTLM_UTILS.create_lm_ntlm_responses(user, pass, self.challenge_key, domain,
869
+ default_name, default_domain, dns_host_name,
870
+ dns_domain_name, chall_MsvAvTimestamp ,
871
+ self.spnopt, ntlm_options)
1061
872
  enc_session_key = ''
873
+ self.sequence_counter = 0
1062
874
  if self.require_signing
1063
-
1064
- server_ntlmssp_flags = blob[cidx + 20, 4].unpack("V")[0]
1065
- # Set default key size and key exchange values
1066
- key_size = 40
1067
- key_exchange = false
1068
- # Remove ntlmssp.negotiate56
1069
- ntlmssp_flags &= 0x7fffffff
1070
- # Remove ntlmssp.negotiatekeyexch
1071
- ntlmssp_flags &= 0xbfffffff
1072
- # Remove ntlmssp.negotiate128
1073
- ntlmssp_flags &= 0xdfffffff
1074
- # Check the keyexchange
1075
- if server_ntlmssp_flags & NTLM_CONST::NEGOTIATE_KEY_EXCH != 0 then
1076
- key_exchange = true
1077
- ntlmssp_flags |= NTLM_CONST::NEGOTIATE_KEY_EXCH
1078
- end
1079
- # Check 128bits
1080
- if server_ntlmssp_flags & NTLM_CONST::NEGOTIATE_128 != 0 then
1081
- key_size = 128
1082
- ntlmssp_flags |= NTLM_CONST::NEGOTIATE_128
1083
- ntlmssp_flags |= NTLM_CONST::NEGOTIATE_56
1084
- # Check 56bits
1085
- else
1086
- if server_ntlmssp_flags & NTLM_CONST::NEGOTIATE_56 != 0 then
1087
- key_size = 56
1088
- ntlmssp_flags |= NTLM_CONST::NEGOTIATE_56
1089
- end
1090
- end
1091
-
1092
- # Generate the user session key
1093
- lanman_weak = false
1094
-
1095
- if self.send_ntlm # Should be default
1096
- if self.usentlm2_session
1097
- if self.use_ntlmv2
1098
- if UTILS.is_pass_ntlm_hash?(pass)
1099
- user_session_key = NTLM_CRYPT::ntlmv2_user_session_key(user,
1100
- [ pass.upcase()[33,65] ].pack('H32'),
1101
- domain,
1102
- self.challenge_key, ntlm_cli_challenge,
1103
- {:pass_is_hash => true})
1104
- else
1105
- user_session_key = NTLM_CRYPT::ntlmv2_user_session_key(user, pass, domain,
1106
- self.challenge_key, ntlm_cli_challenge)
1107
- end
1108
- else
1109
- if UTILS.is_pass_ntlm_hash?(pass)
1110
- user_session_key = NTLM_CRYPT::ntlm2_session_user_session_key([ pass.upcase()[33,65] ].pack('H32'),
1111
- self.challenge_key,
1112
- client_challenge,
1113
- {:pass_is_hash => true})
1114
- else
1115
- user_session_key = NTLM_CRYPT::ntlm2_session_user_session_key(pass, self.challenge_key,
1116
- client_challenge)
1117
- end
1118
- end
1119
- else # lmv1/ntlmv1
1120
- if self.send_lm
1121
- if self.use_lanman_key
1122
- if UTILS.is_pass_ntlm_hash?(pass)
1123
- user_session_key = NTLM_CRYPT::lanman_session_key([ pass.upcase()[0,32] ].pack('H32'),
1124
- self.challenge_key,
1125
- {:pass_is_hash => true})
1126
- else
1127
- user_session_key = NTLM_CRYPT::lanman_session_key(pass, self.challenge_key)
1128
- end
1129
- lanman_weak = true
1130
- else
1131
- if UTILS.is_pass_ntlm_hash?(pass)
1132
- user_session_key = NTLM_CRYPT::ntlmv1_user_session_key([ pass.upcase()[33,65] ].pack('H32'),
1133
- {:pass_is_hash => true})
1134
- else
1135
- user_session_key = NTLM_CRYPT::ntlmv1_user_session_key(pass)
1136
- end
1137
-
1138
- end
1139
- end
1140
- end
1141
- else
1142
- if self.usentlm2_session && self.use_ntlmv2
1143
- if UTILS.is_pass_ntlm_hash?(pass)
1144
- user_session_key = NTLM_CRYPT::lmv2_user_session_key(user, [ pass.upcase()[33,65] ].pack('H32'),
1145
- domain,
1146
- self.challenge_key, client_challenge,
1147
- {:pass_is_hash => true})
1148
- else
1149
- user_session_key = NTLM_CRYPT::lmv2_user_session_key(user, pass, domain,
1150
- self.challenge_key, client_challenge)
1151
- end
1152
- else
1153
- if UTILS.is_pass_ntlm_hash?(pass)
1154
- user_session_key = NTLM_CRYPT::lmv1_user_session_key([ pass.upcase()[0,32] ].pack('H32'),
1155
- {:pass_is_hash => true})
1156
- else
1157
- user_session_key = NTLM_CRYPT::lmv1_user_session_key(pass)
1158
- end
1159
- end
1160
- end
1161
-
1162
- user_session_key = NTLM_CRYPT::make_weak_sessionkey(user_session_key,key_size, lanman_weak)
1163
- self.sequence_counter = 0
1164
- # Sessionkey and encrypted session key
1165
- if key_exchange
1166
- self.signing_key = Rex::Text.rand_text(16)
1167
- enc_session_key = NTLM_CRYPT::encrypt_sessionkey(self.signing_key, user_session_key)
1168
- else
1169
- self.signing_key = user_session_key
1170
- end
1171
-
875
+ self.signing_key, enc_session_key = NTLM_UTILS.create_session_key(server_ntlmssp_flags, user, pass, domain, self.challenge_key,
876
+ client_challenge, ntlm_cli_challenge, ntlm_options)
1172
877
  end
878
+
1173
879
  # Create the security blob data
1174
880
  blob = NTLM_UTILS.make_ntlmssp_secblob_auth(domain, name, user, resp_lm, resp_ntlm, enc_session_key, ntlmssp_flags)
1175
881
 
@@ -2216,6 +1922,8 @@ NTLM_UTILS = Rex::Proto::NTLM::Utils
2216
1922
  attr_accessor :native_os, :native_lm, :encrypt_passwords, :extended_security, :read_timeout, :evasion_opts
2217
1923
  attr_accessor :verify_signature, :use_ntlmv2, :usentlm2_session, :send_lm, :use_lanman_key, :send_ntlm
2218
1924
  attr_accessor :system_time, :system_zone
1925
+ #misc
1926
+ attr_accessor :spnopt # used for SPN
2219
1927
 
2220
1928
  # public read methods
2221
1929
  attr_reader :dialect, :session_id, :challenge_key, :peer_native_lm, :peer_native_os
@@ -182,7 +182,7 @@ attr_accessor :socket, :client, :direct, :shares, :last_share
182
182
  def login( name = '', user = '', pass = '', domain = '',
183
183
  verify_signature = false, usentlmv2 = false, usentlm2_session = true,
184
184
  send_lm = true, use_lanman_key = false, send_ntlm = true,
185
- native_os = 'Windows 2000 2195', native_lm = 'Windows 2000 5.0')
185
+ native_os = 'Windows 2000 2195', native_lm = 'Windows 2000 5.0', spnopt = {})
186
186
 
187
187
  begin
188
188
 
@@ -198,6 +198,8 @@ attr_accessor :socket, :client, :direct, :shares, :last_share
198
198
  self.client.use_lanman_key = use_lanman_key
199
199
  self.client.send_ntlm = send_ntlm
200
200
  self.client.negotiate
201
+ self.client.spnopt = spnopt
202
+
201
203
  ok = self.client.session_setup(user, pass, domain)
202
204
  rescue ::Interrupt
203
205
  raise $!