librex 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +3 -5
- data/Rakefile +26 -0
- data/lib/rex/compat.rb +1 -1
- data/lib/rex/exploitation/javascriptosdetect.rb +125 -62
- data/lib/rex/file.rb +15 -0
- data/lib/rex/io/stream.rb +1 -1
- data/lib/rex/parser/nmap_xml.rb +6 -0
- data/lib/rex/poly/block.rb +9 -0
- data/lib/rex/post/meterpreter/client.rb +0 -8
- data/lib/rex/post/meterpreter/extensions/priv/priv.rb +6 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +1 -1
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_advapi32.rb +49 -35
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_netapi32.rb +26 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb +9 -2
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb +630 -0
- data/lib/rex/post/meterpreter/packet.rb +3 -1
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +143 -57
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +6 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/net.rb +9 -3
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb +6 -4
- data/lib/rex/proto.rb +1 -0
- data/lib/rex/proto/dhcp/server.rb +4 -2
- data/lib/rex/proto/http/packet.rb +5 -6
- data/lib/rex/proto/ntlm.rb +7 -0
- data/lib/rex/proto/ntlm.rb.ut.rb +177 -0
- data/lib/rex/proto/ntlm/base.rb +326 -0
- data/lib/rex/proto/ntlm/constants.rb +74 -0
- data/lib/rex/proto/ntlm/crypt.rb +340 -0
- data/lib/rex/proto/ntlm/exceptions.rb +9 -0
- data/lib/rex/proto/ntlm/message.rb +533 -0
- data/lib/rex/proto/ntlm/utils.rb +358 -0
- data/lib/rex/proto/smb/client.rb +548 -86
- data/lib/rex/proto/smb/client.rb.ut.rb +4 -4
- data/lib/rex/proto/smb/constants.rb +7 -24
- data/lib/rex/proto/smb/crypt.rb +12 -71
- data/lib/rex/proto/smb/exceptions.rb +12 -0
- data/lib/rex/proto/smb/simpleclient.rb +17 -5
- data/lib/rex/proto/smb/utils.rb +3 -460
- data/lib/rex/proto/tftp/server.rb +2 -2
- data/lib/rex/script/base.rb +2 -2
- data/lib/rex/socket.rb +12 -0
- data/lib/rex/socket.rb.ut.rb +31 -10
- data/lib/rex/socket/ssl_tcp_server.rb.ut.rb +15 -5
- data/lib/rex/text.rb +55 -4
- data/lib/rex/ui/output.rb +0 -2
- data/lib/rex/ui/text/dispatcher_shell.rb +95 -10
- data/lib/rex/ui/text/output/buffer.rb +0 -4
- data/lib/rex/ui/text/shell.rb +8 -0
- data/lib/rex/ui/text/table.rb +21 -1
- metadata +15 -19
- data/lib/rex/proto/smb/crypt.rb.ut.rb +0 -20
@@ -207,14 +207,6 @@ class Client
|
|
207
207
|
@@ssl_ctx
|
208
208
|
end
|
209
209
|
|
210
|
-
#
|
211
|
-
# Runs the meterpreter script in the context of a script container
|
212
|
-
#
|
213
|
-
def execute_file(file, args)
|
214
|
-
o = Rex::Script::Meterpreter.new(self, file)
|
215
|
-
o.run(args)
|
216
|
-
end
|
217
|
-
|
218
210
|
##
|
219
211
|
#
|
220
212
|
# Accessors
|
@@ -72,6 +72,12 @@ class Priv < Extension
|
|
72
72
|
if( response.result == 0 and technique != nil )
|
73
73
|
client.core.use( "stdapi" ) if not client.ext.aliases.include?( "stdapi" )
|
74
74
|
client.sys.config.getprivs
|
75
|
+
client.framework.db.report_note(
|
76
|
+
:host => client.sock.peerhost,
|
77
|
+
:workspace => client.framework.db.workspace,
|
78
|
+
:type => "meterpreter.getsystem",
|
79
|
+
:data => {:technique => technique}
|
80
|
+
) rescue nil
|
75
81
|
return [ true, technique ]
|
76
82
|
end
|
77
83
|
|
@@ -620,7 +620,7 @@ class Def_advapi32
|
|
620
620
|
|
621
621
|
railgun.add_function( 'advapi32', 'AccessCheckByType', 'BOOL',[
|
622
622
|
["PBLOB","pSecurityDescriptor","in"],
|
623
|
-
["
|
623
|
+
["LPVOID","PrincipalSelfSid","in"],
|
624
624
|
["DWORD","ClientToken","in"],
|
625
625
|
["DWORD","DesiredAccess","in"],
|
626
626
|
["PBLOB","ObjectTypeList","inout"],
|
@@ -638,7 +638,7 @@ class Def_advapi32
|
|
638
638
|
["PCHAR","ObjectTypeName","in"],
|
639
639
|
["PCHAR","ObjectName","in"],
|
640
640
|
["PBLOB","SecurityDescriptor","in"],
|
641
|
-
["
|
641
|
+
["LPVOID","PrincipalSelfSid","in"],
|
642
642
|
["DWORD","DesiredAccess","in"],
|
643
643
|
["DWORD","AuditType","in"],
|
644
644
|
["DWORD","Flags","in"],
|
@@ -657,7 +657,7 @@ class Def_advapi32
|
|
657
657
|
["PWCHAR","ObjectTypeName","in"],
|
658
658
|
["PWCHAR","ObjectName","in"],
|
659
659
|
["PBLOB","SecurityDescriptor","in"],
|
660
|
-
["
|
660
|
+
["LPVOID","PrincipalSelfSid","in"],
|
661
661
|
["DWORD","DesiredAccess","in"],
|
662
662
|
["DWORD","AuditType","in"],
|
663
663
|
["DWORD","Flags","in"],
|
@@ -672,7 +672,7 @@ class Def_advapi32
|
|
672
672
|
|
673
673
|
railgun.add_function( 'advapi32', 'AccessCheckByTypeResultList', 'BOOL',[
|
674
674
|
["PBLOB","pSecurityDescriptor","in"],
|
675
|
-
["
|
675
|
+
["LPVOID","PrincipalSelfSid","in"],
|
676
676
|
["DWORD","ClientToken","in"],
|
677
677
|
["DWORD","DesiredAccess","in"],
|
678
678
|
["PBLOB","ObjectTypeList","inout"],
|
@@ -690,7 +690,7 @@ class Def_advapi32
|
|
690
690
|
["PCHAR","ObjectTypeName","in"],
|
691
691
|
["PCHAR","ObjectName","in"],
|
692
692
|
["PBLOB","SecurityDescriptor","in"],
|
693
|
-
["
|
693
|
+
["LPVOID","PrincipalSelfSid","in"],
|
694
694
|
["DWORD","DesiredAccess","in"],
|
695
695
|
["DWORD","AuditType","in"],
|
696
696
|
["DWORD","Flags","in"],
|
@@ -710,7 +710,7 @@ class Def_advapi32
|
|
710
710
|
["PCHAR","ObjectTypeName","in"],
|
711
711
|
["PCHAR","ObjectName","in"],
|
712
712
|
["PBLOB","SecurityDescriptor","in"],
|
713
|
-
["
|
713
|
+
["LPVOID","PrincipalSelfSid","in"],
|
714
714
|
["DWORD","DesiredAccess","in"],
|
715
715
|
["DWORD","AuditType","in"],
|
716
716
|
["DWORD","Flags","in"],
|
@@ -730,7 +730,7 @@ class Def_advapi32
|
|
730
730
|
["PWCHAR","ObjectTypeName","in"],
|
731
731
|
["PWCHAR","ObjectName","in"],
|
732
732
|
["PBLOB","SecurityDescriptor","in"],
|
733
|
-
["
|
733
|
+
["LPVOID","PrincipalSelfSid","in"],
|
734
734
|
["DWORD","DesiredAccess","in"],
|
735
735
|
["DWORD","AuditType","in"],
|
736
736
|
["DWORD","Flags","in"],
|
@@ -749,7 +749,7 @@ class Def_advapi32
|
|
749
749
|
["PWCHAR","ObjectTypeName","in"],
|
750
750
|
["PWCHAR","ObjectName","in"],
|
751
751
|
["PBLOB","SecurityDescriptor","in"],
|
752
|
-
["
|
752
|
+
["LPVOID","PrincipalSelfSid","in"],
|
753
753
|
["DWORD","DesiredAccess","in"],
|
754
754
|
["DWORD","AuditType","in"],
|
755
755
|
["DWORD","Flags","in"],
|
@@ -766,7 +766,7 @@ class Def_advapi32
|
|
766
766
|
["PBLOB","pAcl","inout"],
|
767
767
|
["DWORD","dwAceRevision","in"],
|
768
768
|
["DWORD","AccessMask","in"],
|
769
|
-
["
|
769
|
+
["LPVOID","pSid","in"],
|
770
770
|
])
|
771
771
|
|
772
772
|
railgun.add_function( 'advapi32', 'AddAccessAllowedAceEx', 'BOOL',[
|
@@ -774,7 +774,7 @@ class Def_advapi32
|
|
774
774
|
["DWORD","dwAceRevision","in"],
|
775
775
|
["DWORD","AceFlags","in"],
|
776
776
|
["DWORD","AccessMask","in"],
|
777
|
-
["
|
777
|
+
["LPVOID","pSid","in"],
|
778
778
|
])
|
779
779
|
|
780
780
|
railgun.add_function( 'advapi32', 'AddAccessAllowedObjectAce', 'BOOL',[
|
@@ -784,14 +784,14 @@ class Def_advapi32
|
|
784
784
|
["DWORD","AccessMask","in"],
|
785
785
|
["PBLOB","ObjectTypeGuid","in"],
|
786
786
|
["PBLOB","InheritedObjectTypeGuid","in"],
|
787
|
-
["
|
787
|
+
["LPVOID","pSid","in"],
|
788
788
|
])
|
789
789
|
|
790
790
|
railgun.add_function( 'advapi32', 'AddAccessDeniedAce', 'BOOL',[
|
791
791
|
["PBLOB","pAcl","inout"],
|
792
792
|
["DWORD","dwAceRevision","in"],
|
793
793
|
["DWORD","AccessMask","in"],
|
794
|
-
["
|
794
|
+
["LPVOID","pSid","in"],
|
795
795
|
])
|
796
796
|
|
797
797
|
railgun.add_function( 'advapi32', 'AddAccessDeniedAceEx', 'BOOL',[
|
@@ -799,7 +799,7 @@ class Def_advapi32
|
|
799
799
|
["DWORD","dwAceRevision","in"],
|
800
800
|
["DWORD","AceFlags","in"],
|
801
801
|
["DWORD","AccessMask","in"],
|
802
|
-
["
|
802
|
+
["LPVOID","pSid","in"],
|
803
803
|
])
|
804
804
|
|
805
805
|
railgun.add_function( 'advapi32', 'AddAccessDeniedObjectAce', 'BOOL',[
|
@@ -809,7 +809,7 @@ class Def_advapi32
|
|
809
809
|
["DWORD","AccessMask","in"],
|
810
810
|
["PBLOB","ObjectTypeGuid","in"],
|
811
811
|
["PBLOB","InheritedObjectTypeGuid","in"],
|
812
|
-
["
|
812
|
+
["LPVOID","pSid","in"],
|
813
813
|
])
|
814
814
|
|
815
815
|
railgun.add_function( 'advapi32', 'AddAce', 'BOOL',[
|
@@ -824,7 +824,7 @@ class Def_advapi32
|
|
824
824
|
["PBLOB","pAcl","inout"],
|
825
825
|
["DWORD","dwAceRevision","in"],
|
826
826
|
["DWORD","dwAccessMask","in"],
|
827
|
-
["
|
827
|
+
["LPVOID","pSid","in"],
|
828
828
|
["BOOL","bAuditSuccess","in"],
|
829
829
|
["BOOL","bAuditFailure","in"],
|
830
830
|
])
|
@@ -834,7 +834,7 @@ class Def_advapi32
|
|
834
834
|
["DWORD","dwAceRevision","in"],
|
835
835
|
["DWORD","AceFlags","in"],
|
836
836
|
["DWORD","dwAccessMask","in"],
|
837
|
-
["
|
837
|
+
["LPVOID","pSid","in"],
|
838
838
|
["BOOL","bAuditSuccess","in"],
|
839
839
|
["BOOL","bAuditFailure","in"],
|
840
840
|
])
|
@@ -846,7 +846,7 @@ class Def_advapi32
|
|
846
846
|
["DWORD","AccessMask","in"],
|
847
847
|
["PBLOB","ObjectTypeGuid","in"],
|
848
848
|
["PBLOB","InheritedObjectTypeGuid","in"],
|
849
|
-
["
|
849
|
+
["LPVOID","pSid","in"],
|
850
850
|
["BOOL","bAuditSuccess","in"],
|
851
851
|
["BOOL","bAuditFailure","in"],
|
852
852
|
])
|
@@ -880,7 +880,7 @@ class Def_advapi32
|
|
880
880
|
["DWORD","nSubAuthority5","in"],
|
881
881
|
["DWORD","nSubAuthority6","in"],
|
882
882
|
["DWORD","nSubAuthority7","in"],
|
883
|
-
["
|
883
|
+
["PDWORD","pSid","out"],
|
884
884
|
])
|
885
885
|
|
886
886
|
railgun.add_function( 'advapi32', 'AllocateLocallyUniqueId', 'BOOL',[
|
@@ -940,10 +940,20 @@ class Def_advapi32
|
|
940
940
|
["PBLOB","GenericMapping","in"],
|
941
941
|
])
|
942
942
|
|
943
|
+
railgun.add_function( 'advapi32', 'ConvertStringSidToSidA', 'BOOL',[
|
944
|
+
["PCHAR","StringSid","in"],
|
945
|
+
["PDWORD","pSid","out"],
|
946
|
+
])
|
947
|
+
|
948
|
+
railgun.add_function( 'advapi32', 'ConvertStringSidToSidW', 'BOOL',[
|
949
|
+
["PWCHAR","StringSid","in"],
|
950
|
+
["PDWORD","pSid","out"],
|
951
|
+
])
|
952
|
+
|
943
953
|
railgun.add_function( 'advapi32', 'CopySid', 'BOOL',[
|
944
954
|
["DWORD","nDestinationSidLength","in"],
|
945
955
|
["PBLOB","pDestinationSid","out"],
|
946
|
-
["
|
956
|
+
["LPVOID","pSourceSid","in"],
|
947
957
|
])
|
948
958
|
|
949
959
|
railgun.add_function( 'advapi32', 'CreatePrivateObjectSecurity', 'BOOL',[
|
@@ -1098,19 +1108,19 @@ class Def_advapi32
|
|
1098
1108
|
])
|
1099
1109
|
|
1100
1110
|
railgun.add_function( 'advapi32', 'EqualDomainSid', 'BOOL',[
|
1101
|
-
["
|
1102
|
-
["
|
1111
|
+
["LPVOID","pSid1","in"],
|
1112
|
+
["LPVOID","pSid2","in"],
|
1103
1113
|
["PBLOB","pfEqual","out"],
|
1104
1114
|
])
|
1105
1115
|
|
1106
1116
|
railgun.add_function( 'advapi32', 'EqualPrefixSid', 'BOOL',[
|
1107
|
-
["
|
1108
|
-
["
|
1117
|
+
["LPVOID","pSid1","in"],
|
1118
|
+
["LPVOID","pSid2","in"],
|
1109
1119
|
])
|
1110
1120
|
|
1111
1121
|
railgun.add_function( 'advapi32', 'EqualSid', 'BOOL',[
|
1112
|
-
["
|
1113
|
-
["
|
1122
|
+
["LPVOID","pSid1","in"],
|
1123
|
+
["LPVOID","pSid2","in"],
|
1114
1124
|
])
|
1115
1125
|
|
1116
1126
|
railgun.add_function( 'advapi32', 'FileEncryptionStatusA', 'BOOL',[
|
@@ -1128,6 +1138,10 @@ class Def_advapi32
|
|
1128
1138
|
["PBLOB","pAce","out"],
|
1129
1139
|
])
|
1130
1140
|
|
1141
|
+
railgun.add_function( 'advapi32', 'FreeSid', 'LPVOID',[
|
1142
|
+
["LPVOID","pSid","in"],
|
1143
|
+
])
|
1144
|
+
|
1131
1145
|
railgun.add_function( 'advapi32', 'GetAce', 'BOOL',[
|
1132
1146
|
["PBLOB","pAcl","in"],
|
1133
1147
|
["DWORD","dwAceIndex","in"],
|
@@ -1182,7 +1196,7 @@ class Def_advapi32
|
|
1182
1196
|
])
|
1183
1197
|
|
1184
1198
|
railgun.add_function( 'advapi32', 'GetLengthSid', 'DWORD',[
|
1185
|
-
["
|
1199
|
+
["LPVOID","pSid","in"],
|
1186
1200
|
])
|
1187
1201
|
|
1188
1202
|
railgun.add_function( 'advapi32', 'GetNumberOfEventLogRecords', 'BOOL',[
|
@@ -1267,7 +1281,7 @@ class Def_advapi32
|
|
1267
1281
|
])
|
1268
1282
|
|
1269
1283
|
railgun.add_function( 'advapi32', 'GetWindowsAccountDomainSid', 'BOOL',[
|
1270
|
-
["
|
1284
|
+
["LPVOID","pSid","in"],
|
1271
1285
|
["PBLOB","pDomainSid","out"],
|
1272
1286
|
["PDWORD","cbDomainSid","inout"],
|
1273
1287
|
])
|
@@ -1327,11 +1341,11 @@ class Def_advapi32
|
|
1327
1341
|
])
|
1328
1342
|
|
1329
1343
|
railgun.add_function( 'advapi32', 'IsValidSid', 'BOOL',[
|
1330
|
-
["
|
1344
|
+
["LPVOID","pSid","in"],
|
1331
1345
|
])
|
1332
1346
|
|
1333
1347
|
railgun.add_function( 'advapi32', 'IsWellKnownSid', 'BOOL',[
|
1334
|
-
["
|
1348
|
+
["LPVOID","pSid","in"],
|
1335
1349
|
["DWORD","WellKnownSidType","in"],
|
1336
1350
|
])
|
1337
1351
|
|
@@ -1351,7 +1365,7 @@ class Def_advapi32
|
|
1351
1365
|
["DWORD","dwLogonType","in"],
|
1352
1366
|
["DWORD","dwLogonProvider","in"],
|
1353
1367
|
["PDWORD","phToken","out"],
|
1354
|
-
["
|
1368
|
+
["PDWORD","ppLogonSid","out"],
|
1355
1369
|
["PBLOB","ppProfileBuffer","out"],
|
1356
1370
|
["PDWORD","pdwProfileLength","out"],
|
1357
1371
|
["PBLOB","pQuotaLimits","out"],
|
@@ -1364,7 +1378,7 @@ class Def_advapi32
|
|
1364
1378
|
["DWORD","dwLogonType","in"],
|
1365
1379
|
["DWORD","dwLogonProvider","in"],
|
1366
1380
|
["PDWORD","phToken","out"],
|
1367
|
-
["
|
1381
|
+
["PDWORD","ppLogonSid","out"],
|
1368
1382
|
["PBLOB","ppProfileBuffer","out"],
|
1369
1383
|
["PDWORD","pdwProfileLength","out"],
|
1370
1384
|
["PBLOB","pQuotaLimits","out"],
|
@@ -1401,7 +1415,7 @@ class Def_advapi32
|
|
1401
1415
|
|
1402
1416
|
railgun.add_function( 'advapi32', 'LookupAccountSidA', 'BOOL',[
|
1403
1417
|
["PCHAR","lpSystemName","in"],
|
1404
|
-
["
|
1418
|
+
["LPVOID","Sid","in"],
|
1405
1419
|
["PCHAR","Name","out"],
|
1406
1420
|
["PDWORD","cchName","inout"],
|
1407
1421
|
["PCHAR","ReferencedDomainName","out"],
|
@@ -1411,7 +1425,7 @@ class Def_advapi32
|
|
1411
1425
|
|
1412
1426
|
railgun.add_function( 'advapi32', 'LookupAccountSidW', 'BOOL',[
|
1413
1427
|
["PWCHAR","lpSystemName","in"],
|
1414
|
-
["
|
1428
|
+
["LPVOID","Sid","in"],
|
1415
1429
|
["PWCHAR","Name","out"],
|
1416
1430
|
["PDWORD","cchName","inout"],
|
1417
1431
|
["PWCHAR","ReferencedDomainName","out"],
|
@@ -1676,7 +1690,7 @@ class Def_advapi32
|
|
1676
1690
|
["WORD","wType","in"],
|
1677
1691
|
["WORD","wCategory","in"],
|
1678
1692
|
["DWORD","dwEventID","in"],
|
1679
|
-
["
|
1693
|
+
["LPVOID","lpUserSid","in"],
|
1680
1694
|
["WORD","wNumStrings","in"],
|
1681
1695
|
["DWORD","dwDataSize","in"],
|
1682
1696
|
["PBLOB","lpStrings","in"],
|
@@ -1688,7 +1702,7 @@ class Def_advapi32
|
|
1688
1702
|
["WORD","wType","in"],
|
1689
1703
|
["WORD","wCategory","in"],
|
1690
1704
|
["DWORD","dwEventID","in"],
|
1691
|
-
["
|
1705
|
+
["LPVOID","lpUserSid","in"],
|
1692
1706
|
["WORD","wNumStrings","in"],
|
1693
1707
|
["DWORD","dwDataSize","in"],
|
1694
1708
|
["PBLOB","lpStrings","in"],
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Rex
|
2
|
+
module Post
|
3
|
+
module Meterpreter
|
4
|
+
module Extensions
|
5
|
+
module Stdapi
|
6
|
+
module Railgun
|
7
|
+
module Def
|
8
|
+
|
9
|
+
class Def_netapi32
|
10
|
+
|
11
|
+
def self.add_imports(railgun)
|
12
|
+
|
13
|
+
railgun.add_dll('netapi32')
|
14
|
+
|
15
|
+
railgun.add_function( 'netapi32', 'NetUserDel', 'DWORD',[
|
16
|
+
["PWCHAR","servername","in"],
|
17
|
+
["PWCHAR","username","in"],
|
18
|
+
])
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
end; end; end; end; end; end; end
|
25
|
+
|
26
|
+
|
@@ -30,6 +30,7 @@ require 'pp'
|
|
30
30
|
require 'enumerator'
|
31
31
|
require 'rex/post/meterpreter/extensions/stdapi/railgun/api_constants'
|
32
32
|
require 'rex/post/meterpreter/extensions/stdapi/railgun/tlv'
|
33
|
+
require 'rex/post/meterpreter/extensions/stdapi/railgun/util'
|
33
34
|
require 'rex/post/meterpreter/extensions/stdapi/railgun/model'
|
34
35
|
require 'rex/post/meterpreter/extensions/stdapi/railgun/multicall'
|
35
36
|
|
@@ -56,6 +57,9 @@ class Railgun
|
|
56
57
|
|
57
58
|
# Load the multi-caller
|
58
59
|
@multicaller = MultiCaller.new( @client, self, @win_consts )
|
60
|
+
|
61
|
+
# Load utility class
|
62
|
+
@util = Util.new( self, @client.platform )
|
59
63
|
end
|
60
64
|
|
61
65
|
# read data from a memory address on the host (useful for working with LPVOID parameters)
|
@@ -140,6 +144,9 @@ class Railgun
|
|
140
144
|
when 'iphlpapi'
|
141
145
|
require 'rex/post/meterpreter/extensions/stdapi/railgun/def/def_iphlpapi'
|
142
146
|
Def::Def_iphlpapi.add_imports(self)
|
147
|
+
when 'netapi32'
|
148
|
+
require 'rex/post/meterpreter/extensions/stdapi/railgun/def/def_netapi32'
|
149
|
+
Def::Def_netapi32.add_imports(self)
|
143
150
|
when 'advapi32'
|
144
151
|
require 'rex/post/meterpreter/extensions/stdapi/railgun/def/def_advapi32'
|
145
152
|
Def::Def_advapi32.add_imports(self)
|
@@ -189,8 +196,8 @@ class Railgun
|
|
189
196
|
@multicaller.call(functions)
|
190
197
|
end
|
191
198
|
|
192
|
-
attr_accessor :client, :dll, :multicaller, :win_consts
|
199
|
+
attr_accessor :client, :dll, :multicaller, :win_consts, :util
|
193
200
|
|
194
201
|
end
|
195
202
|
|
196
|
-
end; end; end; end; end; end
|
203
|
+
end; end; end; end; end; end
|
@@ -0,0 +1,630 @@
|
|
1
|
+
require 'rex/post/meterpreter/extensions/stdapi/railgun/model'
|
2
|
+
|
3
|
+
module Rex
|
4
|
+
module Post
|
5
|
+
module Meterpreter
|
6
|
+
module Extensions
|
7
|
+
module Stdapi
|
8
|
+
module Railgun
|
9
|
+
class Util
|
10
|
+
|
11
|
+
# Bring in some useful string manipulation utility functions
|
12
|
+
include DLLHelper
|
13
|
+
|
14
|
+
# Data type size info: http://msdn.microsoft.com/en-us/library/s3f49ktz(v=vs.80).aspx
|
15
|
+
PRIMITIVE_TYPE_SIZES = {
|
16
|
+
:int => 4,
|
17
|
+
:__int8 => 1,
|
18
|
+
:__int16 => 2,
|
19
|
+
:__int32 => 4,
|
20
|
+
:__int64 => 8,
|
21
|
+
:bool => 1,
|
22
|
+
:char => 1,
|
23
|
+
:short => 2,
|
24
|
+
:long => 4,
|
25
|
+
:long_long => 8,
|
26
|
+
:float => 4,
|
27
|
+
:double => 8,
|
28
|
+
:long_double => 8,
|
29
|
+
:wchar_t => 2,
|
30
|
+
}
|
31
|
+
|
32
|
+
# Maps a data type to its corresponding primitive or special type :pointer
|
33
|
+
# Note, primitive types are mapped to themselves
|
34
|
+
# typedef info: http://msdn.microsoft.com/en-us/library/aa383751(v=vs.85).aspx
|
35
|
+
TYPE_DEFINITIONS = {
|
36
|
+
##
|
37
|
+
# Primitives
|
38
|
+
##
|
39
|
+
:int => :int,
|
40
|
+
:__int8 => :__int8,
|
41
|
+
:__int16 => :__int16,
|
42
|
+
:__int32 => :__int32,
|
43
|
+
:__int64 => :__int64,
|
44
|
+
:bool => :bool,
|
45
|
+
:char => :char,
|
46
|
+
:short => :short,
|
47
|
+
:long => :long,
|
48
|
+
:long_long => :long_long,
|
49
|
+
:float => :float,
|
50
|
+
:double => :double,
|
51
|
+
:long_double => :long_double,
|
52
|
+
:wchar_t => :wchar_t,
|
53
|
+
##
|
54
|
+
# Non-pointers
|
55
|
+
##
|
56
|
+
#typedef WORD ATOM;
|
57
|
+
:ATOM => :short,
|
58
|
+
#typedef int BOOL;
|
59
|
+
:BOOL => :int,
|
60
|
+
#typedef BYTE BOOLEAN;
|
61
|
+
:BOOLEAN => :char,
|
62
|
+
#typedef unsigned char BYTE;
|
63
|
+
:BYTE => :char,
|
64
|
+
#typedef char CHAR;
|
65
|
+
:CHAR => :char,
|
66
|
+
#typedef DWORD COLORREF;
|
67
|
+
:COLORREF => :long,
|
68
|
+
#typedef unsigned long DWORD;
|
69
|
+
:DWORD => :long,
|
70
|
+
#typedef unsigned int DWORD32;
|
71
|
+
:DWORD32 => :int,
|
72
|
+
#typedef unsigned __int64 DWORD64;
|
73
|
+
:DWORD64 => :__int64,
|
74
|
+
#typedef float FLOAT;
|
75
|
+
:FLOAT => :float,
|
76
|
+
#typedef int HFILE;
|
77
|
+
:HFILE => :int,
|
78
|
+
#typedef LONG HRESULT;
|
79
|
+
:HRESULT => :long,
|
80
|
+
#typedef int INT;
|
81
|
+
:INT => :int,
|
82
|
+
#typedef signed int INT32;
|
83
|
+
:INT32 => :int,
|
84
|
+
#typedef signed __int64 INT64;
|
85
|
+
:INT64 => :__int64,
|
86
|
+
#typedef WORD LANGID;
|
87
|
+
:LANGID => :short,
|
88
|
+
#typedef DWORD LCID;
|
89
|
+
:LCID => :long,
|
90
|
+
#typedef DWORD LCTYPE;
|
91
|
+
:LCTYPE => :long,
|
92
|
+
#typedef DWORD LGRPID;
|
93
|
+
:LGRPID => :long,
|
94
|
+
#typedef long LONG;
|
95
|
+
:LONG => :long,
|
96
|
+
#typedef signed int LONG32;
|
97
|
+
:LONG32 => :int,
|
98
|
+
#typedef __int64 LONG64;
|
99
|
+
:LONG64 => :__int64,
|
100
|
+
#typedef PDWORD PLCID;
|
101
|
+
:PLCID => :pointer,
|
102
|
+
#typedef LPVOID SC_LOCK;
|
103
|
+
:SC_LOCK => :pointer,
|
104
|
+
#typedef short SHORT;
|
105
|
+
:SHORT => :short,
|
106
|
+
#typedef unsigned char UCHAR;
|
107
|
+
:UCHAR => :char,
|
108
|
+
#typedef unsigned int UINT;
|
109
|
+
:UINT => :int,
|
110
|
+
#typedef unsigned int UINT32;
|
111
|
+
:UINT32 => :int,
|
112
|
+
#typedef unsigned long ULONG;
|
113
|
+
:ULONG => :long,
|
114
|
+
#typedef unsigned int ULONG32;
|
115
|
+
:ULONG32 => :int,
|
116
|
+
#typedef unsigned __int64 ULONG64;
|
117
|
+
:ULONG64 => :__int64,
|
118
|
+
#typedef unsigned short USHORT;
|
119
|
+
:USHORT => :short,
|
120
|
+
#typedef wchar_t WCHAR;
|
121
|
+
:WCHAR => :wchar_t,
|
122
|
+
#typedef unsigned short WORD;
|
123
|
+
:WORD => :short,
|
124
|
+
##
|
125
|
+
# Pointers declared with *
|
126
|
+
##
|
127
|
+
#typedef DWORD* LPCOLORREF;
|
128
|
+
:LPCOLORREF => :pointer,
|
129
|
+
#typedef void* LPCVOID;
|
130
|
+
:LPCVOID => :pointer,
|
131
|
+
#typedef WCHAR* LPCWSTR;
|
132
|
+
:LPCWSTR => :pointer,
|
133
|
+
#typedef DWORD* LPDWORD;
|
134
|
+
:LPDWORD => :pointer,
|
135
|
+
#typedef HANDLE* LPHANDLE;
|
136
|
+
:LPHANDLE => :pointer,
|
137
|
+
#typedef int* LPINT;
|
138
|
+
:LPINT => :pointer,
|
139
|
+
#typedef long* LPLONG;
|
140
|
+
:LPLONG => :pointer,
|
141
|
+
#typedef CHAR* LPSTR;
|
142
|
+
:LPSTR => :pointer,
|
143
|
+
#typedef void* LPVOID;
|
144
|
+
:LPVOID => :pointer,
|
145
|
+
#typedef WORD* LPWORD;
|
146
|
+
:LPWORD => :pointer,
|
147
|
+
#typedef WCHAR* LPWSTR;
|
148
|
+
:LPWSTR => :pointer,
|
149
|
+
#typedef BOOL* PBOOL;
|
150
|
+
:PBOOL => :pointer,
|
151
|
+
#typedef BOOLEAN* PBOOLEAN;
|
152
|
+
:PBOOLEAN => :pointer,
|
153
|
+
#typedef BYTE* PBYTE;
|
154
|
+
:PBYTE => :pointer,
|
155
|
+
#typedef CHAR* PCHAR;
|
156
|
+
:PCHAR => :pointer,
|
157
|
+
#typedef CHAR* PCSTR;
|
158
|
+
:PCSTR => :pointer,
|
159
|
+
#typedef WCHAR* PCWSTR;
|
160
|
+
:PCWSTR => :pointer,
|
161
|
+
#typedef DWORD* PDWORD;
|
162
|
+
:PDWORD => :pointer,
|
163
|
+
#typedef DWORDLONG* PDWORDLONG;
|
164
|
+
:PDWORDLONG => :pointer,
|
165
|
+
#typedef DWORD_PTR* PDWORD_PTR;
|
166
|
+
:PDWORD_PTR => :pointer,
|
167
|
+
#typedef DWORD32* PDWORD32;
|
168
|
+
:PDWORD32 => :pointer,
|
169
|
+
#typedef DWORD64* PDWORD64;
|
170
|
+
:PDWORD64 => :pointer,
|
171
|
+
#typedef FLOAT* PFLOAT;
|
172
|
+
:PFLOAT => :pointer,
|
173
|
+
#typedef HANDLE* PHANDLE;
|
174
|
+
:PHANDLE => :pointer,
|
175
|
+
#typedef HKEY* PHKEY;
|
176
|
+
:PHKEY => :pointer,
|
177
|
+
#typedef int* PINT;
|
178
|
+
:PINT => :pointer,
|
179
|
+
#typedef INT_PTR* PINT_PTR;
|
180
|
+
:PINT_PTR => :pointer,
|
181
|
+
#typedef INT32* PINT32;
|
182
|
+
:PINT32 => :pointer,
|
183
|
+
#typedef INT64* PINT64;
|
184
|
+
:PINT64 => :pointer,
|
185
|
+
#typedef LONG* PLONG;
|
186
|
+
:PLONG => :pointer,
|
187
|
+
#typedef LONGLONG* PLONGLONG;
|
188
|
+
:PLONGLONG => :pointer,
|
189
|
+
#typedef LONG_PTR* PLONG_PTR;
|
190
|
+
:PLONG_PTR => :pointer,
|
191
|
+
#typedef LONG32* PLONG32;
|
192
|
+
:PLONG32 => :pointer,
|
193
|
+
#typedef LONG64* PLONG64;
|
194
|
+
:PLONG64 => :pointer,
|
195
|
+
#typedef SHORT* PSHORT;
|
196
|
+
:PSHORT => :pointer,
|
197
|
+
#typedef SIZE_T* PSIZE_T;
|
198
|
+
:PSIZE_T => :pointer,
|
199
|
+
#typedef SSIZE_T* PSSIZE_T;
|
200
|
+
:PSSIZE_T => :pointer,
|
201
|
+
#typedef CHAR* PSTR;
|
202
|
+
:PSTR => :pointer,
|
203
|
+
#typedef TBYTE* PTBYTE;
|
204
|
+
:PTBYTE => :pointer,
|
205
|
+
#typedef TCHAR* PTCHAR;
|
206
|
+
:PTCHAR => :pointer,
|
207
|
+
#typedef UCHAR* PUCHAR;
|
208
|
+
:PUCHAR => :pointer,
|
209
|
+
#typedef UINT* PUINT;
|
210
|
+
:PUINT => :pointer,
|
211
|
+
#typedef UINT_PTR* PUINT_PTR;
|
212
|
+
:PUINT_PTR => :pointer,
|
213
|
+
#typedef UINT32* PUINT32;
|
214
|
+
:PUINT32 => :pointer,
|
215
|
+
#typedef UINT64* PUINT64;
|
216
|
+
:PUINT64 => :pointer,
|
217
|
+
#typedef ULONG* PULONG;
|
218
|
+
:PULONG => :pointer,
|
219
|
+
#typedef ULONGLONG* PULONGLONG;
|
220
|
+
:PULONGLONG => :pointer,
|
221
|
+
#typedef ULONG_PTR* PULONG_PTR;
|
222
|
+
:PULONG_PTR => :pointer,
|
223
|
+
#typedef ULONG32* PULONG32;
|
224
|
+
:PULONG32 => :pointer,
|
225
|
+
#typedef ULONG64* PULONG64;
|
226
|
+
:PULONG64 => :pointer,
|
227
|
+
#typedef USHORT* PUSHORT;
|
228
|
+
:PUSHORT => :pointer,
|
229
|
+
#typedef void* PVOID;
|
230
|
+
:PVOID => :pointer,
|
231
|
+
#typedef WCHAR* PWCHAR;
|
232
|
+
:PWCHAR => :pointer,
|
233
|
+
#typedef WORD* PWORD;
|
234
|
+
:PWORD => :pointer,
|
235
|
+
#typedef WCHAR* PWSTR;
|
236
|
+
:PWSTR => :pointer,
|
237
|
+
#typedef HANDLE HACCEL;
|
238
|
+
:HACCEL => :pointer,
|
239
|
+
##
|
240
|
+
# Handles
|
241
|
+
##
|
242
|
+
#typedef PVOID HANDLE;
|
243
|
+
:HANDLE => :pointer,
|
244
|
+
#typedef HANDLE HBITMAP;
|
245
|
+
:HBITMAP => :pointer,
|
246
|
+
#typedef HANDLE HBRUSH;
|
247
|
+
:HBRUSH => :pointer,
|
248
|
+
#typedef HANDLE HCOLORSPACE;
|
249
|
+
:HCOLORSPACE => :pointer,
|
250
|
+
#typedef HANDLE HCONV;
|
251
|
+
:HCONV => :pointer,
|
252
|
+
#typedef HANDLE HCONVLIST;
|
253
|
+
:HCONVLIST => :pointer,
|
254
|
+
#typedef HANDLE HDC;
|
255
|
+
:HDC => :pointer,
|
256
|
+
#typedef HANDLE HDDEDATA;
|
257
|
+
:HDDEDATA => :pointer,
|
258
|
+
#typedef HANDLE HDESK;
|
259
|
+
:HDESK => :pointer,
|
260
|
+
#typedef HANDLE HDROP;
|
261
|
+
:HDROP => :pointer,
|
262
|
+
#typedef HANDLE HDWP;
|
263
|
+
:HDWP => :pointer,
|
264
|
+
#typedef HANDLE HENHMETAFILE;
|
265
|
+
:HENHMETAFILE => :pointer,
|
266
|
+
#typedef HANDLE HFONT;
|
267
|
+
:HFONT => :pointer,
|
268
|
+
#typedef HANDLE HGDIOBJ;
|
269
|
+
:HGDIOBJ => :pointer,
|
270
|
+
#typedef HANDLE HGLOBAL;
|
271
|
+
:HGLOBAL => :pointer,
|
272
|
+
#typedef HANDLE HHOOK;
|
273
|
+
:HHOOK => :pointer,
|
274
|
+
#typedef HANDLE HICON;
|
275
|
+
:HICON => :pointer,
|
276
|
+
#typedef HANDLE HINSTANCE;
|
277
|
+
:HINSTANCE => :pointer,
|
278
|
+
#typedef HANDLE HKEY;
|
279
|
+
:HKEY => :pointer,
|
280
|
+
#typedef HANDLE HKL;
|
281
|
+
:HKL => :pointer,
|
282
|
+
#typedef HANDLE HLOCAL;
|
283
|
+
:HLOCAL => :pointer,
|
284
|
+
#typedef HANDLE HMENU;
|
285
|
+
:HMENU => :pointer,
|
286
|
+
#typedef HANDLE HMETAFILE;
|
287
|
+
:HMETAFILE => :pointer,
|
288
|
+
#typedef HANDLE HPALETTE;
|
289
|
+
:HPALETTE => :pointer,
|
290
|
+
#typedef HANDLE HPEN;
|
291
|
+
:HPEN => :pointer,
|
292
|
+
#typedef HANDLE HRGN;
|
293
|
+
:HRGN => :pointer,
|
294
|
+
#typedef HANDLE HRSRC;
|
295
|
+
:HRSRC => :pointer,
|
296
|
+
#typedef HANDLE HSZ;
|
297
|
+
:HSZ => :pointer,
|
298
|
+
#typedef HANDLE WINSTA;
|
299
|
+
:WINSTA => :pointer,
|
300
|
+
#typedef HANDLE HWND;
|
301
|
+
:HWND => :pointer,
|
302
|
+
#typedef HANDLE SC_HANDLE;
|
303
|
+
:SC_HANDLE => :pointer,
|
304
|
+
#typedef HANDLE SERVICE_STATUS_HANDLE;
|
305
|
+
:SERVICE_STATUS_HANDLE => :pointer,
|
306
|
+
}
|
307
|
+
|
308
|
+
# param 'railgun' is a Railgun instance.
|
309
|
+
# param 'platform' is a value like client.platform
|
310
|
+
def initialize(railgun, platform)
|
311
|
+
@railgun = railgun
|
312
|
+
@is_64bit = is_64bit_platform?(platform)
|
313
|
+
end
|
314
|
+
|
315
|
+
# Given a packed pointer, unpacks it according to architecture
|
316
|
+
def unpack_pointer(packed_pointer)
|
317
|
+
if is_64bit
|
318
|
+
# XXX: Only works if attacker and victim are like-endianed
|
319
|
+
packed_pointer.unpack('Q')[0]
|
320
|
+
else
|
321
|
+
packed_pointer.unpack('V')[0]
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
###
|
326
|
+
# Summary: Returns true if pointer will be considered a 'null' pointer
|
327
|
+
#
|
328
|
+
# If given nil, returns true
|
329
|
+
# If given 0, returns true
|
330
|
+
# If given a string, if 0 after unpacking, returns true
|
331
|
+
# false otherwise
|
332
|
+
##
|
333
|
+
def is_null_pointer(pointer)
|
334
|
+
if pointer.class == String
|
335
|
+
pointer = unpack_pointer(pointer)
|
336
|
+
end
|
337
|
+
|
338
|
+
return pointer.nil? || pointer == 0
|
339
|
+
end
|
340
|
+
|
341
|
+
###
|
342
|
+
# Summary: Reads null-terminated unicode strings from memory.
|
343
|
+
#
|
344
|
+
# Given a pointer to a null terminated array of WCHARs, return a ruby string
|
345
|
+
# Null pointers cause an empty string to be returned
|
346
|
+
##
|
347
|
+
def read_wstring(pointer, length = nil)
|
348
|
+
# Return an empty string for null pointers
|
349
|
+
if is_null_pointer(pointer)
|
350
|
+
return ''
|
351
|
+
end
|
352
|
+
|
353
|
+
# If length not provided, use lstrlenW
|
354
|
+
if length.nil?
|
355
|
+
length = railgun.kernel32.lstrlenW(pointer)['return']
|
356
|
+
end
|
357
|
+
|
358
|
+
# Retrieve the array of characters
|
359
|
+
chars = read_array(:WCHAR, length, pointer)
|
360
|
+
|
361
|
+
# Concatenate the characters and convert to a ruby string
|
362
|
+
str = uniz_to_str(chars.join(''))
|
363
|
+
|
364
|
+
return str
|
365
|
+
end
|
366
|
+
|
367
|
+
###
|
368
|
+
# Summary: Read a given number of bytes from memory or from a provided buffer.
|
369
|
+
#
|
370
|
+
# If 'buffer' is not provided, read 'size' bytes from the client's memory
|
371
|
+
# If 'buffer' is provided, reads 'size' characters from the index of 'address'
|
372
|
+
##
|
373
|
+
def memread(address, size, buffer = nil)
|
374
|
+
if buffer.nil?
|
375
|
+
return railgun.memread(address, size)
|
376
|
+
else
|
377
|
+
return buffer[address .. (address + size - 1)]
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
381
|
+
# Read and unpack a pointer from the given buffer at a given offset
|
382
|
+
def read_pointer(buffer, offset = 0)
|
383
|
+
unpack_pointer(buffer[offset, (offset + pointer_size)])
|
384
|
+
end
|
385
|
+
|
386
|
+
# Reads data structures and several windows data types
|
387
|
+
def read_data(type, position, buffer = nil)
|
388
|
+
if buffer.nil?
|
389
|
+
buffer = memread(position, sizeof_type(type))
|
390
|
+
position = 0
|
391
|
+
end
|
392
|
+
|
393
|
+
# If we're asked to read a data structure, deligate to read_struct
|
394
|
+
if is_struct_type?(type)
|
395
|
+
return read_struct(type, buffer, position)
|
396
|
+
end
|
397
|
+
|
398
|
+
# If the type is an array with a given size...
|
399
|
+
# BYTE[3] for example or BYTE[ENCRYPTED_PWLEN] or even PDWORD[23]
|
400
|
+
if is_array_type?(type)
|
401
|
+
# Separate the element type from the size of the array
|
402
|
+
element_type, length = split_array_type(type)
|
403
|
+
|
404
|
+
# Have read_array take care of the rest
|
405
|
+
return read_array(element_type, length, position, buffer)
|
406
|
+
end
|
407
|
+
|
408
|
+
size = sizeof_type(type)
|
409
|
+
raw = memread(position, size, buffer)
|
410
|
+
|
411
|
+
# read/unpack data for the types we have hard-coded support for
|
412
|
+
case type
|
413
|
+
when :LPWSTR
|
414
|
+
# null-terminated string of 16-bit Unicode characters
|
415
|
+
return read_wstring(read_pointer(raw))
|
416
|
+
when :DWORD
|
417
|
+
# Both on x86 and x64, DWORD is 32 bits
|
418
|
+
return raw.unpack('V').first
|
419
|
+
when :BOOL
|
420
|
+
return raw.unpack('l').first == 1
|
421
|
+
when :LONG
|
422
|
+
return raw.unpack('l').first
|
423
|
+
end
|
424
|
+
|
425
|
+
#If nothing worked thus far, return it raw
|
426
|
+
return raw
|
427
|
+
end
|
428
|
+
|
429
|
+
# Read 'length' number of instances of 'type' from 'bufptr'
|
430
|
+
# bufptr is an index in 'buffer' or, if buffer is nil, a memory address
|
431
|
+
def read_array(type, length, bufptr, buffer = nil)
|
432
|
+
if length <= 0
|
433
|
+
return []
|
434
|
+
end
|
435
|
+
|
436
|
+
size = sizeof_type(type)
|
437
|
+
# Grab the bytes that the array consists of
|
438
|
+
buffer = memread(bufptr, size * length, buffer)
|
439
|
+
|
440
|
+
offset = 0
|
441
|
+
|
442
|
+
1.upto(length).map do |n|
|
443
|
+
data = read_data(type, offset, buffer)
|
444
|
+
|
445
|
+
offset = offset + size
|
446
|
+
|
447
|
+
data
|
448
|
+
end
|
449
|
+
end
|
450
|
+
|
451
|
+
# construct the data structure described in 'definition' from 'buffer'
|
452
|
+
# starting from the index 'offset'
|
453
|
+
def read_struct(definition, buffer, offset = 0)
|
454
|
+
data = {}
|
455
|
+
|
456
|
+
offsets = struct_offsets(definition, offset)
|
457
|
+
|
458
|
+
definition.each do |mapping|
|
459
|
+
key, data_type = mapping
|
460
|
+
|
461
|
+
data[key] = read_data(data_type, offsets.shift, buffer)
|
462
|
+
end
|
463
|
+
|
464
|
+
data
|
465
|
+
end
|
466
|
+
|
467
|
+
|
468
|
+
# Returns true if the data type is a pointer, false otherwise
|
469
|
+
def is_pointer_type?(type)
|
470
|
+
return TYPE_DEFINITIONS[type] == :pointer
|
471
|
+
end
|
472
|
+
|
473
|
+
# Returns whether the given type represents an array of another type
|
474
|
+
# For example BYTE[3], BYTE[ENCRYPTED_PWLEN], or even PDWORD[23]
|
475
|
+
def is_array_type?(type)
|
476
|
+
return type =~ /^\w+\[\w+\]$/ ? true : false
|
477
|
+
end
|
478
|
+
|
479
|
+
# Returns true if the type passed describes a data structure, false otherwise
|
480
|
+
def is_struct_type?(type)
|
481
|
+
return type.class == Array
|
482
|
+
end
|
483
|
+
|
484
|
+
|
485
|
+
# Returns the pointer size for this architecture
|
486
|
+
def pointer_size
|
487
|
+
is_64bit ? 8 : 4
|
488
|
+
end
|
489
|
+
|
490
|
+
# Return the size, in bytes, of the given type
|
491
|
+
def sizeof_type(type)
|
492
|
+
if is_pointer_type?(type)
|
493
|
+
return pointer_size
|
494
|
+
end
|
495
|
+
|
496
|
+
if is_array_type?(type)
|
497
|
+
element_type, length = split_array_type(type)
|
498
|
+
|
499
|
+
return length * sizeof_type(element_type)
|
500
|
+
end
|
501
|
+
|
502
|
+
if is_struct_type?(type)
|
503
|
+
return sizeof_struct(type)
|
504
|
+
end
|
505
|
+
|
506
|
+
if TYPE_DEFINITIONS.has_key?(type)
|
507
|
+
primitive = TYPE_DEFINITIONS[type]
|
508
|
+
|
509
|
+
if primitive == :pointer
|
510
|
+
return pointer_size
|
511
|
+
end
|
512
|
+
|
513
|
+
if PRIMITIVE_TYPE_SIZES.has_key?(primitive)
|
514
|
+
return PRIMITIVE_TYPE_SIZES[primitive]
|
515
|
+
else
|
516
|
+
raise "Type #{type} was mapped to non-existent primitive #{primitive}"
|
517
|
+
end
|
518
|
+
end
|
519
|
+
|
520
|
+
raise "Unable to determine size for type #{type}."
|
521
|
+
end
|
522
|
+
|
523
|
+
# Calculates the size of the struct after alignment
|
524
|
+
def sizeof_struct(struct)
|
525
|
+
offsets = struct_offsets(struct, 0)
|
526
|
+
last_data_size = sizeof_type(struct.last[1])
|
527
|
+
size_no_padding = offsets.last + last_data_size
|
528
|
+
|
529
|
+
return size_no_padding + calc_padding(size_no_padding)
|
530
|
+
end
|
531
|
+
|
532
|
+
# Given a description of a data structure, returns an array containing
|
533
|
+
# the offset from the beginning for each subsequent element, taking into
|
534
|
+
# consideration alignment and padding
|
535
|
+
def struct_offsets(definition, offset)
|
536
|
+
padding = 0
|
537
|
+
offsets = []
|
538
|
+
|
539
|
+
definition.each do |mapping|
|
540
|
+
key, data_type = mapping
|
541
|
+
|
542
|
+
if sizeof_type(data_type) > padding
|
543
|
+
offset = offset + padding
|
544
|
+
end
|
545
|
+
|
546
|
+
offsets.push(offset)
|
547
|
+
|
548
|
+
offset = offset + sizeof_type(data_type)
|
549
|
+
|
550
|
+
padding = calc_padding(offset)
|
551
|
+
end
|
552
|
+
|
553
|
+
offsets
|
554
|
+
end
|
555
|
+
|
556
|
+
# http://en.wikipedia.org/wiki/Data_structure_alignment
|
557
|
+
def required_alignment
|
558
|
+
is_64bit ? 8 : 4
|
559
|
+
end
|
560
|
+
|
561
|
+
# Bytes that needed to be added to be aligned
|
562
|
+
def calc_padding(offset)
|
563
|
+
align = required_alignment
|
564
|
+
|
565
|
+
# If offset is not aligned...
|
566
|
+
if (offset % align) != 0
|
567
|
+
# Calculate padding needed to be aligned
|
568
|
+
align - (offset & (align - 1))
|
569
|
+
else
|
570
|
+
0
|
571
|
+
end
|
572
|
+
end
|
573
|
+
|
574
|
+
# Given an explicit array definition (e.g. BYTE[23]) return size (e.g. 23) and
|
575
|
+
# and type (e.g. BYTE). If a constant is given, attempt to resolve it
|
576
|
+
# that constant
|
577
|
+
def split_array_type(type)
|
578
|
+
if type =~ /^(\w+)\[(\w+)\]$/
|
579
|
+
element_type = $1
|
580
|
+
length = $2
|
581
|
+
|
582
|
+
unless length =~ /^\d+$/
|
583
|
+
length = railgun.const(length)
|
584
|
+
end
|
585
|
+
|
586
|
+
return element_type, length
|
587
|
+
else
|
588
|
+
raise "Can not split non-array type #{type}"
|
589
|
+
end
|
590
|
+
end
|
591
|
+
|
592
|
+
# Returns true if given platform has 64bit architecture
|
593
|
+
# expects client.platform
|
594
|
+
def is_64bit_platform?(platform)
|
595
|
+
platform =~ /win64/
|
596
|
+
end
|
597
|
+
|
598
|
+
###
|
599
|
+
# Summary:
|
600
|
+
# Evaluates a bit field, returning a hash representing the meaning
|
601
|
+
# and state of each bit.
|
602
|
+
#
|
603
|
+
# Parameters:
|
604
|
+
# value: a bit field represented by a Fixnum
|
605
|
+
# mappings: { 'WINAPI_CONSTANT_NAME' => :descriptive_symbol, ... }
|
606
|
+
#
|
607
|
+
# Returns:
|
608
|
+
# { :descriptive_symbol => true/false, ... }
|
609
|
+
##
|
610
|
+
def judge_bit_field(value, mappings)
|
611
|
+
flags = {}
|
612
|
+
rg = railgun
|
613
|
+
|
614
|
+
mappings.each do |constant_name, key|
|
615
|
+
flags[key] = (value & rg.const(constant_name)) != 0
|
616
|
+
end
|
617
|
+
|
618
|
+
flags
|
619
|
+
end
|
620
|
+
|
621
|
+
protected
|
622
|
+
|
623
|
+
attr_accessor :railgun, :is_64bit
|
624
|
+
end # Util
|
625
|
+
end # Railgun
|
626
|
+
end # Stdapi
|
627
|
+
end # Extensions
|
628
|
+
end # Meterpreter
|
629
|
+
end # Post
|
630
|
+
end # Rex
|