Sunday, November 29, 2009

Compiling and running Windows programs on Linux

While the title of this post could make you wonder why you ever want to do this, there is actually a scenario where this comes handy. Let's say you downloaded exploit code or for instance the sample source code of the Database hackers handbook. In both cases you may encounter source code that requires a Windows development environment to compile. While Microsoft offers free express editions for many of their development tools, you still need a copy of Windows somewhere.

Last week I decided to try a different route with MinGW, which is a port of GCC that can be used to develop native Windows applications. If you want to use MinGW under Linux you have to build a cross compiler. Historically this has been a difficult task. On Gentoo Linux however there is a package named crossdev. Once installed this package automates the task of building a cross compiler. With the following command you can build a MinGW cross compiler:

$ sudo crossdev -t i686-mingw32

Building the cross compiler may take some time. Once installed the following command could be tried to compile one of the source code samples from the Database hackers handbook:

$ i686-mingw32-gcc C2_2.cpp -o dbsnmp.exe

However, you will receive receive several errors:
C2_2.cpp: In function ‘int StartWinsock()’:
C2_2.cpp:83: error: ‘isalpha’ was not declared in this scope
C2_2.cpp: In function ‘int QueryDBSNMP(int)’:
C2_2.cpp:128: error: ‘con’ was not declared in this scope
C2_2.cpp:128: error: ‘nect’ was not declared in this scope
C2_2.cpp:134: error: invalid conversion from ‘unsigned char*’ to ‘const char*’
C2_2.cpp:134: error:   initializing argument 2 of ‘int send(SOCKET, const char*, int, int)’
C2_2.cpp:135: error: invalid conversion from ‘unsigned char*’ to ‘char*’
C2_2.cpp:135: error:   initializing argument 2 of ‘int recv(SOCKET, char*, int, int)’
C2_2.cpp:142: error: ‘PrintResponse’ was not declared in this scope
C2_2.cpp:143: error: invalid conversion from ‘unsigned char*’ to ‘const char*’
C2_2.cpp:143: error:   initializing argument 2 of ‘int send(SOCKET, const char*, int, int)’
C2_2.cpp:144: error: invalid conversion from ‘unsigned char*’ to ‘char*’
C2_2.cpp:144: error:   initializing argument 2 of ‘int recv(SOCKET, char*, int, int)’
C2_2.cpp:152: error: invalid conversion from ‘unsigned char*’ to ‘const char*’
C2_2.cpp:152: error:   initializing argument 2 of ‘int send(SOCKET, const char*, int, int)’
C2_2.cpp:153: error: invalid conversion from ‘unsigned char*’ to ‘char*’
C2_2.cpp:153: error:   initializing argument 2 of ‘int recv(SOCKET, char*, int, int)’
C2_2.cpp:166: error: invalid conversion from ‘unsigned char*’ to ‘const char*’
C2_2.cpp:166: error:   initializing argument 2 of ‘int send(SOCKET, const char*, int, int)’
C2_2.cpp:167: error: invalid conversion from ‘unsigned char*’ to ‘char*’
C2_2.cpp:167: error:   initializing argument 2 of ‘int recv(SOCKET, char*, int, int)’

The error on line 83, about the isalpha function can be fixed by including ctype.h. The error about line 128 are caused by the extra minus sign in the connect function name. Script kiddie protection, who knows? The rest of the errors could be fixed by casting (char *) the send and receive buffers. Trying to compile again leaves us with one error:

C2_2.cpp:143: error: ‘PrintResponse’ was not declared in this scope

This error is caused by a missing declaration of the PrintResponse() function at the top of the source file. Once that error is fixed we encounter linking errors:
/tmp/ccf47BD7.o:C2_2.cpp:(.text+0x125): undefined reference to `_WSACleanup@0'
/tmp/ccf47BD7.o:C2_2.cpp:(.text+0x158): undefined reference to `_WSAStartup@8'
/tmp/ccf47BD7.o:C2_2.cpp:(.text+0x18d): undefined reference to `_WSACleanup@0'
/tmp/ccf47BD7.o:C2_2.cpp:(.text+0x1b9): undefined reference to `_gethostbyname@4'
/tmp/ccf47BD7.o:C2_2.cpp:(.text+0x20c): undefined reference to `_inet_addr@4'
/tmp/ccf47BD7.o:C2_2.cpp:(.text+0x2cf): undefined reference to `_socket@12'
/tmp/ccf47BD7.o:C2_2.cpp:(.text+0x30a): undefined reference to `_htons@4'
/tmp/ccf47BD7.o:C2_2.cpp:(.text+0x32b): undefined reference to `_bind@12'
/tmp/ccf47BD7.o:C2_2.cpp:(.text+0x343): undefined reference to `_closesocket@4'
/tmp/ccf47BD7.o:C2_2.cpp:(.text+0x368): undefined reference to `_htons@4'
/tmp/ccf47BD7.o:C2_2.cpp:(.text+0x38d): undefined reference to `_connect@12'
/tmp/ccf47BD7.o:C2_2.cpp:(.text+0x3a5): undefined reference to `_closesocket@4'
/tmp/ccf47BD7.o:C2_2.cpp:(.text+0x3e2): undefined reference to `_send@16'
/tmp/ccf47BD7.o:C2_2.cpp:(.text+0x40d): undefined reference to `_recv@16'
/tmp/ccf47BD7.o:C2_2.cpp:(.text+0x424): undefined reference to `_closesocket@4'
/tmp/ccf47BD7.o:C2_2.cpp:(.text+0x476): undefined reference to `_send@16'
/tmp/ccf47BD7.o:C2_2.cpp:(.text+0x4a1): undefined reference to `_recv@16'
/tmp/ccf47BD7.o:C2_2.cpp:(.text+0x4b8): undefined reference to `_closesocket@4'
/tmp/ccf47BD7.o:C2_2.cpp:(.text+0x50a): undefined reference to `_send@16'
/tmp/ccf47BD7.o:C2_2.cpp:(.text+0x535): undefined reference to `_recv@16'
/tmp/ccf47BD7.o:C2_2.cpp:(.text+0x54c): undefined reference to `_closesocket@4'
/tmp/ccf47BD7.o:C2_2.cpp:(.text+0x58b): undefined reference to `_closesocket@4'
/tmp/ccf47BD7.o:C2_2.cpp:(.text+0x5c3): undefined reference to `_send@16'
/tmp/ccf47BD7.o:C2_2.cpp:(.text+0x5ee): undefined reference to `_recv@16'
/tmp/ccf47BD7.o:C2_2.cpp:(.text+0x605): undefined reference to `_closesocket@4'
/tmp/ccf47BD7.o:C2_2.cpp:(.text+0x626): undefined reference to `_closesocket@4'
collect2: ld returned 1 exit status

All these functions are part of winsock library on Windows. What we need to do now is locate winsock.h on the local file system (use the one in the mingw directory, when multiple are found) and add the following options to our compile command:


$ i686-mingw32-gcc C2_2.cpp -o dbsnmp.exe -L/usr/i686-mingw32/usr/include/ -lws2_32

Finally our source compiled and linked and now we can run it with wine:
$ wine dbsnmp.exe



    Oracle DBSNMP Tool

    C:\>dbsnmp.exe host status|stop

    David Litchfield
    davidl@ngssoftware.com
    4th June 2004

Yeah, a running program at last!

Monday, November 23, 2009

Building your own ethernet tap for just over 25 euros

Recently I was looking for a solution to place an IDS in front of my firewall and monitor my internet connection. This way I would be able to detect all attacks, even the ones that get blocked by my firewall. My ADSL modem is in bridging mode and my firewall has the external IP address of the connection. I have a Siemens modem and although the embedded XSH shell is not very well documented it does not seem like it has a SPAN port feature like some of the Speedtouch ADSL modems, which are also commonly used for broadband connections in the Netherlands.

While I could have run Snort on my firewall, I decided I wanted to have a separate system for monitoring. I looked at buying a 100Mbit tap of the shelve, but those are still too expensive for home use. I searched the internet to see if it would be possible to build my own. Several people already succeeded in building their own, so I decided to give it a shot.

In order to build a tap for 10/100Mbit you need four ethernet ports. Two to connect both hosts and two ports which will receive a copy of either the sent (TX) or receive (RX) pair of wires from the ethernet cable. So each tap port will receive only half of the connection, as shown in the diagram below, which used to be on the Snort website:

This means that the tap ports can only receive traffic, and will not be able to send out any network traffic. This will prevent you from creating dangerous loop holes bypassing your firewall.

I made a small shopping list and tried to get the supplies at the local computer or electronic shops. Many examples use ethernet mounting wall systems with four ports, but those are hard to get in the shops. I ended up taking a different route and I bought two ethernet cat 5e surface mounting wall boxes at the local computer shop. Once you take of the plastic covers you end up with to metal boxes as shown below:


When the covers are taken of you can see the punch through blades for the individual wires, which allow you to do the wiring without soldering. I carefully stripped 15 cm of ethernet cable and took the twisted wire pairs out. Following the coloring diagram above I wired the wire pairs through the punch through blades with a screw driver. It is important to keep the wire pairs twisted, in order to minimize interference. The picture below shows the end result:


Although the wiring does not look too clean in the picture, it turns out it works very well for over a week now, without any interface errors on the firewall. The ethernet tap cost me just over 25 euros and a few hours to build.

The last step is to combine both tap ports into one virtual interface on the monitoring system, which will see the complete traffic flow in both directions. This can be done by using the interface bonding option (CONFIG_BONDING) of the Linux kernel. On Gentoo systems the following configuration in /etc/init.d/net allows the virtual bond interface at boot time:

slaves_bond0="eth0 eth1 "
config_bond0=( "null" )
config_eth0=( "null" )
config_eth1=( "null" )
RC_NEED_bond0="net.eth0 neth.eth1"

Of course the proper symlinks need to be in place in /etc/init.d/ for all network interfaces that must be started at boot time. Tests with tcpdump and wireshark on the bond0 interface show the complete traffic flow between the systems. Next step is to install Sguil on the monitoring system!