librex 0.0.6 → 0.0.7
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.
- 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
|