Rats on rats? How crap!


So, I am in the process of learning about software vulnerabilities and the ways to discover them. Of course, I read a lot and I experiment a lot: my experiments or labs, as they call it, are book-based and community-based. Sort of: take the Gray Hat Hacking book, learn a bit about a software called rats, and then run it against a C code I have delopyed somewhere. I do know that this software has been archived – according to Google – so I wasn’t expecting a modern tool. But, hey! Most of C-coded errors are still the same, so I thought it would be fine to start using this tool before trying others.

First things first: I decided to ran the rats tool that came pre-installed on my Kali Linux. Now, you must know I tend to get any single tool’s version before going further with my experimentation, to ensure I am always using the latest and stablest tool so far. This time I did the same, and instead of getting a version string or an unknown parameter error, this came up instead:

root@kali:~# rats –version
Segmentation fault


So fine, rats’s got a BUG

To find out what was happening behind the scenes, I got its source code and build dependencies and I compiled rats:

# apt-get build-dep rats && apt-get source rats

# cd rats-2.3/ ; ./configure && make

In order to determine where exactly the segmentation fault was fired, I ran rats inside a gdb debugging session:

(gdb) set args –version
(gdb) r
Starting program: /root/rats-2.3/rats –version

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff78a8eb4 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) bt
#0 0x00007ffff78a8eb4 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007ffff78dcae6 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#2 0x00007ffff78dd91b in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#3 0x00007ffff78dda03 in getopt_long () from /lib/x86_64-linux-gnu/libc.so.6
#4 0x0000000000401767 in main (argc=2, argv=0x7fffffffe6c8) at main.c:288

As clearly shown above, the crash happened somewhere inside the getopt_long call. However, this call belongs to the libc, so it was unlikely to have a bug there; line 288 in main.c was quite another thing, though:

while ((i = getopt_long(argc, argv, "a:d:hil:Rrw:x",long_options,&option_index)) != -1)

It was a trivial piece of code in charge of parsing the program parameters from the CLI: and, because I typed the –version flag, getopt_long was called with all the valid parameters: the short and the long ones. As you can see from the previous code-snippet, the long options were stored in the long_options variable, of type static struct option:

 static struct option long_options[] = {
      {"noheader", 0,0,0},
      {"nofooter", 0,0,0},
      {"quiet", 0,0,0},
      {"resultsonly", 0,0,0},
      {"columns", 0,0,0},
      {"context", 0,0,0},
      {"all-static", 0,0,0}

It seemed obvious that this structure was somehow not right … reading through the getopt_long man-page, I found out this:

The last element of the array has to be filled with zeros.

The fix

So, I needed to fill the last array element for the long_options structure with zeros. To do so, I added this code right after the last array entry:


I recompiled an ran the tool again:

./rats –version
./rats: unrecognized option ‘–version’

Now we are talking! It is time to start analysing code! What about … running rats on rats? Would you even dare? 😉

See ya next time, folks!