librex 0.0.12 → 0.0.13

Sign up to get free protection for your applications and to get access to all the features.
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 $!