Ruby for Pentesters #1: Use Modules For Lists Of Constants
Thomas Ptacek | July 3rd, 2008 | Filed Under: Uncategorized
Almost 2 years ago, Dino declared Python to be the “lingua-franca of over-the-hill hackers”, boldly asserting that 5 out of 6 security hackers under the age of 30 preferred Ruby instead. Being 30 at the time, I was an easy psychological target for this argument. I made the switch and haven’t regretted it. You can tell me all you want that “named nested functions are just as good as lambdas”, or that “you can fake Ruby blocks with a for loop and a generator”. Ruby is just nicer to write testing code in, and makes me feel at least 2 years younger and less experienced than I really am. Thanks, Ruby!
I’ve been meaning to write a long post about our house Ruby style, and some of the Ruby tips and tricks we’ve picked up along the way. But every time I sit down to write it, that post starts sounding a lot like work. So instead, I’d like to inaugurate a new series of much easier posts: Ruby for Pen-testers.
Where was I?
1. Use Modules For Lists Of Constants
If you test protocols or C code, you run into lists of magic numbers all the time. For example, here’s a bit of ptrace(2):
#define PT_READ_I 1 /* read word in child’s I space */
#define PT_READ_D 2 /* read word in child’s D space */
#define PT_READ_U 3 /* read word in child’s user structure */
#define PT_WRITE_I 4 /* write word in child’s I space */
#define PT_WRITE_D 5 /* write word in child’s D space */
#define PT_WRITE_U 6 /* write word in child’s user structure */
#define PT_CONTINUE 7 /* continue the child */
#define PT_KILL 8 /* kill the child process */
This is gross, but it’s C code, so you give them a break. But here’s some code from Pedram’s PyDbg:
TH32CS_SNAPPROCESS = 0x00000002
TH32CS_SNAPTHREAD = 0x00000004
TH32CS_SNAPMODULE = 0x00000008
TH32CS_INHERIT = 0x80000000
Now, Pedram does have the excuse of writing in Python. But here’s Ruby-MySql:
COM_QUIT = 1
COM_INIT_DB = 2
COM_QUERY = 3
This code has no excuse. (Here’s a rewrite that is much faster). Now, let’s look at net-ssh; if you haven’t read Jamis’ net-ssh code, you shouldn’t write any more packet processing code until you do.
# Transport layer generic messages
DISCONNECT = 1
IGNORE = 2
UNIMPLEMENTED = 3
DEBUG = 4
# …
end
Getting closer. But not there yet. Here’s an even better way:
CARRY = (1<< 0)
X0 = (1<< 1)
PARITY = (1<< 2)
# …
VINT = (1<< 19)
VINTPENDING = (1<< 20)
CPUID = (1<< 21)
end
That’s right: one module per set of constants. In other words, substitute “module” for “enum”. This has many benefits:
It’s clean. You can immediately find all the related magic numbers, both from the list, and by looking at code that uses the magic numbers —- you see Ragweed::EFlags::CARRY, you know to look for “EFlags”.
Modules come with special bonus features.
For instance:
def to_name_hash
@name_hash ||= constants.map {|k| [k.intern, const_get(k.intern)]}.to_hash
end
def to_value_hash
@key_hash ||= constants.map {|k| [const_get(k.intern), k.intern]}.to_hash
end
end
EFlags.to_value_hash[1 << 19] # => :VINT
… which is super nice when you’re printing out the contents of packets.


Add New Comment
Viewing 14 Comments
Thanks. Your comment is awaiting approval by a moderator.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
Add New Comment
Trackbacks