Skip to content

Commit 7d1fadb

Browse files
committed
Add a test module for railgun api calls
1 parent cab19dc commit 7d1fadb

File tree

2 files changed

+94
-1
lines changed

2 files changed

+94
-1
lines changed

lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_kernel32.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1419,7 +1419,7 @@ def self.create_dll(dll_path = 'kernel32')
14191419
["DWORD","nSize","in"],
14201420
])
14211421

1422-
dll.add_function( 'GetModuleHandleA', 'DWORD',[
1422+
dll.add_function( 'GetModuleHandleA', 'HANDLE',[
14231423
["PCHAR","lpModuleName","in"],
14241424
])
14251425

test/modules/post/test/railgun.rb

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
2+
require 'msf/core'
3+
4+
lib = File.join(Msf::Config.install_root, "test", "lib")
5+
require 'module_test'
6+
7+
class MetasploitModule < Msf::Post
8+
9+
include Msf::ModuleTest::PostTest
10+
include Msf::Post::Windows::Railgun
11+
12+
def initialize(info={})
13+
super( update_info( info,
14+
'Name' => 'Railgun API Tests',
15+
'Description' => %q{ This module will test railgun api functions},
16+
'License' => MSF_LICENSE,
17+
'Author' => [ 'Spencer McIntyre'],
18+
'Platform' => [ 'windows' ]
19+
))
20+
end
21+
22+
def test_api_function_calls
23+
24+
it "Results should include error information" do
25+
ret = true
26+
result = session.railgun.kernel32.GetCurrentProcess()
27+
ret &&= result['GetLastError'] == 0
28+
ret &&= result['ErrorMessage'].is_a? String
29+
end
30+
31+
it "Should support functions with no parameters" do
32+
ret = true
33+
result = session.railgun.kernel32.GetCurrentThread()
34+
ret &&= result['GetLastError'] == 0
35+
ret &&= result['return'] != 0
36+
end
37+
38+
it "Should support functions with literal parameters" do
39+
ret = true
40+
result = session.railgun.kernel32.Sleep(50)
41+
ret &&= result['GetLastError'] == 0
42+
end
43+
44+
it "Should support functions with in/out/inout parameter types" do
45+
ret = true
46+
# DnsHostnameToComputerNameA is ideal because it uses all 3 types see:
47+
# https://msdn.microsoft.com/en-us/library/windows/desktop/ms724244(v=vs.85).aspx
48+
result = session.railgun.kernel32.DnsHostnameToComputerNameA('localhost', 64, 64)
49+
ret &&= result['GetLastError'] == 0
50+
ret &&= result['ComputerName'].is_a? String
51+
ret &&= result['nSize'].to_i == result['ComputerName'].length
52+
end
53+
54+
it "Should support reading memory" do
55+
ret = true
56+
result = client.railgun.kernel32.GetModuleHandleA('kernel32')
57+
ret &&= result['GetLastError'] == 0
58+
ret &&= result['return'] != 0
59+
return false unless ret
60+
61+
handle = result['return']
62+
mz_header = client.railgun.memread(handle, 4)
63+
ret &&= mz_header == "MZ\x90\x00"
64+
end
65+
66+
it "Should support writing memory" do
67+
ret = true
68+
result = client.railgun.kernel32.GetProcessHeap()
69+
ret &&= result['GetLastError'] == 0
70+
ret &&= result['return'] != 0
71+
return false unless ret
72+
73+
buffer_size = 32
74+
handle = result['return']
75+
result = client.railgun.kernel32.HeapAlloc(handle, 0, buffer_size)
76+
ret &&= result['GetLastError'] == 0
77+
ret &&= result['return'] != 0
78+
return false unless ret
79+
80+
buffer_value = Rex::Text.rand_text_alphanumeric(buffer_size)
81+
buffer = result['return']
82+
ret &&= client.railgun.memwrite(buffer, buffer_value, buffer_size)
83+
ret &&= client.railgun.memread(buffer, buffer_size) == buffer_value
84+
85+
client.railgun.kernel32.HeapFree(handle, 0, buffer)
86+
ret
87+
end
88+
89+
end
90+
91+
end
92+
93+

0 commit comments

Comments
 (0)