From Collaborative RCE Tool Library

Jump to: navigation, search

Ragweed

Tool name: Ragweed
Rating: 0.0 (0 votes)
Author: Matasano Security                        
Website: http://www.matasano.com/log/1799/ruby-for-pentesters-the-dark-side-i-ragweed/
Current version:
Last updated:
Direct D/L link: N/A
License type: Free / Open Source
Description: Ragweed is available as a gem through github:

sudo gem install tduehr-ragweed


Why a scriptable debugger?


When reversing, the usual debugging tools for developers aren’t as useful. They’re built for stepping interactively through programs you have source code for. They don’t generally have methods to get data out.

Reversing also requires being able to do mean and nasty things to the running process. When tracing calls, you want to watch how they interact. The last thing you want to do is anything manual. Automation is a requirement.

Also helpful is the ability to automate information gathering tasks, or the ability to dynamically add, remove or change breakpoints. These features are why scriptable debuggers have been created: To play with black boxes in a more dynamic and seedier manner.

What’s available already?


There are already scriptable debuggers out there. The most notable are PaiMei/PyDbg, Immunity Debugger and IDA.

PaiMei is written in Python, bills itself as “a reverse engineer’s swiss army knife” and uses the Python ctypes library for low level win32 calls.

Immunity Debugger is a GUI debuggger for win32 that uses Python for its scripting functionality.

IDA Pro is largely a win32 disassembler, but it is scriptable, again in Python, and includes a debugging module.

Before I get run off by a screaming mob with pitchforks, flightless birds, members of the family bovidae, etc., I will also mention GDB which has a library in development (libgdb) and can be scripted through macros.

With the exception of GDB which runs on most platforms and has its own macro language, these all share two common problems: Win32 and Python. Matasano is a Ruby shop. We like Ruby. It is good to us. We also wanted a tool for non-Win32 applications. But mostly, we just wanted something in Ruby.

Enter Ragweed


I’m going to stick to the OSX side of Ragweed for this article since I’m most familiar with it and there is still work to be done to unify the (currently) three debugging APIs —- Win32, Linux, and OSX —- inside Ragweed.

Under the hood, Ragweed (on OSX) uses Ruby/DL to perform the various low level system calls necessary to create a debugger. (More about that in my post from last year). These calls are abstracted somewhat to provide a smoother, more Ruby-like interface.

There are two caveats for Ragweed in OSX:

* Due to the changes in Ruby 1.9 to DL, it is currently incompatible with 1.9.
* Also, under OSX, Ragweed wants to run as root due to restrictions on
Code:

task_for_pid

.

A quick example (this we can do in IRB):


# debugging ftp using default signal handlers, printing registers every stop and logging calls to _lpwd

require ‘ragweed’
class DebugFtp < Debuggerosx

# print the registers every time the process stops

def on_stop(signal)

puts "Stopped with signal #{signal}"

self.threads.each {|t| self.get_registers(t).dump}

end

end

# no process lookup by name yet

d = DebugFtp.new(pid) # where pid is the id of ftp for this example

# set breakpoint for lpwd

d.breakpoint_set(0x420f,‘lpwd’, (bpl = lambda do | t, r, s | puts "#{ s.breakpoints[r.eip].first.function } hit in thread #{ t }\n"; end))

d.install_breakpoints

d.continue

d.loop #loop until child exits

# now go do stuff in in your other terminal window running ftp

That’s it. We just override the signal handlers for the signals we want to know about (or not), attach to a running process, set and install breakpoints, and it’s off to the traces. A simple hit tracer is only a CSV file and read loop away from this.

Want info on a region of memory?

d.region_info(0x0,:basic).dump

What about:

thread_info

?

d.threadinfo(threadid).dump

Break stuff by playing with registers?

regs = d.get_registers(thread_id) regs.eip = 0x420f d.set_registers(thread_id, regs)

Grope through the child’s memory?

Ragweed::Wraposx::vm_read(d.task, address, size) #returns a string of child's memory

There you have it. It’s not pretty but it’s only begun.
Related URLs: No related URLs have been submitted for this tool yet


RSS feed Feed containing all updates for this tool.

You are welcome to add your own useful notes about this tool, for others to see!



If you find that any information for the tool above is missing, outdated or incorrect, please edit it!
(please also edit it if you think it fits well in some additional category, since this can also be controlled)


Views
Category Navigation Tree
   Code Coverage Tools  (13)
   Code Ripping Tools  (2)
   .NET Debuggers  (4)
   Debugger Libraries  (5)
   Ring 0 Debuggers  (8)
   Ring 3 Debuggers  (15)
   Symbol Retrievers  (4)
   VM Debugging Tools  (1)
   Helper Tools  (3)
   Hex Editors  (13)
   Memory Patchers  (7)
   Packers  (20)
   Profiler Tools  (11)
   String Finders  (10)
   Tool Hiding Tools  (7)
   Tracers  (22)
   Needs New Category  (3)