Friday 28 September 2012

rssh - reverse secure shell

Sometimes we want what seems impossible, we want to access machines in private networks. The problem is that these machines are behind a NAT device, and therefore do not have a public IP address. In these cases, what we need is a reverse shell.

But there's a catch: we don't want a simple shell, we want a standard encrypted connection: an ssh connection.

Let's consider the following machines:
- a public machine: myhost.example.com
- a machine behind NAT: 10.0.0.1

We want to connect from myhost.example.com to 10.0.0.1. Because it is behind NAT, it does not have a public IP address and therefore we can not ask it for a connection.

However, with a little help from 10.0.0.1, we can do it. At 10.0.0.1 we do:

ssh -N -R 2222:localhost:22 me@myhost.example.com


This will create a tunnel-only connection to the public machine, with a reverse tunnel from the 2222 public machine port to the 22 port of 10.0.0.1.

This means that any packets going to port 2222 of the public machine will reach port 22 of 10.0.0.1, which is exacly what we need to start an ssh connection.

Because of this cool reverse tunnel, now we can connect to 10.0.0.1 by doing the following at the public machine:

ssh -p 2222 me@localhost

Friday 27 July 2012

command line remote control

Regularly, I work on machines connected to TVs which respond to interactions with remote control devices. Yesterday, while doing some actions at the device command line, I realized that I don't need the remote control. All I need to control applications is in the shell. This is an Android based machine, so it is possible to move the menu selector to the left by executing:

$ input keyevent 21 

I made a conf file with some keys I needed:

$ cat androidKeys.sh
KEY_LEFT=21
KEY_RIGHT=22
KEY_UP=19
KEY_DOWN=20
KEY_BACK=4
KEY_ENTER=66
KEY_MENU=3
KEY_VOLUME_UP=24
KEY_VOLUME_DOWN=25
KEY_VOLUME_MUTE=164


And created a script to easily send commands:

$ cat send.sh
#!/usr/bin/env bash

source ./androidKeys.sh
HOST_IP=$1
EVENT_KEY=$2

KEY_CODE=$(eval "echo \$${EVENT_KEY}")

ssh $HOST_IP "input keyevent ${KEY_CODE}" 

Noticed the eval "echo \$${EVENT_KEY}"? It lets you obtain a variable's value by using the content of another variable to indicate the name of the first variable. So, the $EVENT_KEY may contain 'KEY_LEFT', which when passed to eval is evaluated as "echo $KEY_LEFT" , giving us the value of $KEY_LEFT.

Then I did:
 
$ ./send.sh 10.0.0.123 KEY_LEFT

And the cursor moved to the left. This is better, I thought, but it could be even better. I could be using the directional keys on my keyboard.

But it is not a simple task, the following has to possible:
1) obtain the key pressed
2) convert into a numerical representation
3) translate that representation into our KEY_* codes
4) invoke send.sh, passing the host IP and the key code

For the first task, an stty/dd combo comes to rescue. We use stty in raw mode, and capture three bytes of input with dd (bs=3). This will allow us to capture single and multi byte keys.
Then we parse this string (ord function below), by iterating over it and converting each character to a number by printfing it as integer.
Finally, we pass the numerical sequence returned by ord to another charCodeTokey function which translates to our known KEY_* codes.

$ cat auto.sh 
#!/usr/bin/env bash

HOST_IP=$1

function charCodeToKey ()
{
        CHAR_CODE=($@)
        CHAR_STRING="${CHAR_CODE[@]}"

        [ "$CHAR_STRING" = "27 91 68" ] && echo 'KEY_LEFT'
        [ "$CHAR_STRING" = "27 91 67" ] && echo 'KEY_RIGHT'
        [ "$CHAR_STRING" = "27 91 65" ] && echo 'KEY_UP'
        [ "$CHAR_STRING" = "27 91 66" ] && echo 'KEY_DOWN'
        [ "$CHAR_STRING" = "127" ]      && echo 'KEY_BACK'
        [ "$CHAR_STRING" = "13" ]       && echo 'KEY_ENTER'
        [ "$CHAR_STRING" = "27 79 72" ] && echo 'KEY_MENU'
        [ "$CHAR_STRING" = "43" ]       && echo 'KEY_VOLUME_UP'
        [ "$CHAR_STRING" = "45" ]       && echo 'KEY_VOLUME_DOWN'

}

function ord()
{
        str="$@"
        strLen=${#str}
        for i in $(seq 0 $(($strLen - 1)))
        do
                c=${str:$i:1}
                printf '%d ' "'$c"
        done
}

while :
do
        old_tty_settings=$(stty -g)
        stty raw -echo
        DATA=$(dd bs=3 count=1 2>/dev/null)
        stty "$old_tty_settings"

        CHARS=$(ord $DATA)

        if [ "${CHARS}" = "3 " ]
        then
                exit
        fi 

        KEY_EVENT=$(charCodeToKey "$CHARS")

        if [ "$KEY_EVENT" != "" ]
        then
                echo $KEY_EVENT
                ./send.sh $HOST_IP $KEY_EVENT
        else
                echo "Unsupported key"
        fi
done


One caveat of using stty's this way is that after starting the infinite while loop, it is impossible to stop. This is because stty captures the ^C command, and translates it too. So we need to check for it (the if [ "${CHARS}" = "3 " ].. exit above), and exit the script. Also, we must save the terminal settings ( old_tty_settings=$(stty -g) ) and put it back ( stty "$old_tty_settings" ), otherwise the terminal will be unusable after we exit the script.

So now I can control all my applications on the TV through my shell, no more remotes :)
Well, maybe not all applications yet. These scripts will need more key codes... and mouse support.

Saturday 21 July 2012

typescript ssh sessions

Recently, I have found myself doing some investigative work on potentially compromised machines. Since I am more used to the opposite position, I have been finding new tools and techniques. Among other, I have found this interesting command script, which can be used to prove which actions where taken on a given machine by an investigator. When executed, script starts a new shell and keeps a record of all characters printed to the screen. The output is saved to a file passed as argument, and may be viewed using cat.
One interesting feature is the ability to capture an ssh session:


[root@web0 ~]# script 192_168_1_38_me_ssh.script -c 'ssh me@192.168.1.38' 
(...)
[root@web0 ~]# exit 
[root@web0 ~]# cat 192_168_1_38_me_ssh.script | cut -c1-75
Script started on Sat 21 Jul 2012 05:34:03 PM WEST
me@192.168.1.38's password: 
Welcome to Ubuntu 12.04 LTS (GNU/Linux 3.2.0-24-generic-pae i686)

 * Documentation:  https://help.ubuntu.com/
Last login: Sat Jul 21 17:30:25 2012 from 192.168.1.37
me@minibuntu:~$ ls -lat /
total 84
drwxr-xr-x 14 root root   500 Jul 21 17:34 run
drwxrwxrwt  4 root root  4096 Jul 21 17:28 tmp
drwxr-xr-x 14 root root  4040 Jul 21 17:27 dev
drwxr-xr-x 81 root root  4096 Jul 21 17:27 etc
drwxr-xr-x 13 root root     0 Jul 21 17:27 sys
dr-xr-xr-x 72 root root     0 Jul 21 17:27 proc
drwxr-xr-x 11 root root  4096 Jul 21 17:27 var
drwxr-xr-x  4 root root  4096 May 20 04:24 opt
drwx------  3 root root  4096 May 20 02:47 root
drwxr-xr-x  3 root root  4096 May 18 23:24 home
drwxr-xr-x  2 root root  4096 May 18 23:23 sbin
drwxr-xr-x  3 root root  4096 May 18 23:23 boot
drwxr-xr-x  2 root root  4096 May 18 23:18 bin
drwxr-xr-x 20 root root  4096 May 18 23:18 lib
drwxr-xr-x 22 root root  4096 May 18 22:56 .
drwxr-xr-x 22 root root  4096 May 18 22:56 ..
lrwxrwxrwx  1 root root    33 May 18 22:56 vmlinuz -> boot/vmli
lrwxrwxrwx  1 root root    37 May 18 22:56 initrd.img -> /boot/
drwxr-xr-x 10 root root  4096 May 18 22:43 usr
drwxr-xr-x  2 root root  4096 May 18 22:43 srv
drwxr-xr-x  2 root root  4096 May 18 22:34 media
drwx------  2 root root 16384 May 18 22:34 lost+found
drwxr-xr-x  2 root root  4096 Apr 19 10:32 mnt
drwxr-xr-x  2 root root  4096 Mar  5 13:48 selinux
me@minibuntu:~$ ps auxew
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.4  0.7   3504  1860 ?        Ss   17:27   0:01 /sbin/init
root         2  0.0  0.0      0     0 ?        S    17:27   0:00 [kthreadd]
root         3  0.0  0.0      0     0 ?        S    17:27   0:00 [ksoftirqd
root         4  0.0  0.0      0     0 ?        S    17:27   0:00 [kworker/0
root         5  0.1  0.0      0     0 ?        S    17:27   0:00 [kworker/u
root         6  0.0  0.0      0     0 ?        S    17:27   0:00 [migration
root         7  0.0  0.0      0     0 ?        S    17:27   0:00 [watchdog/
root         8  0.0  0.0      0     0 ?        S<   17:27   0:00 [cpuset]
root         9  0.0  0.0      0     0 ?        S<   17:27   0:00 [khelper]
root        10  0.0  0.0      0     0 ?        S    17:27   0:00 [kdevtmpfs
root        11  0.0  0.0      0     0 ?        S<   17:27   0:00 [netns]
root        12  0.0  0.0      0     0 ?        S    17:27   0:00 [sync_supe
root        13  0.0  0.0      0     0 ?        S    17:27   0:00 [bdi-defau
root        14  0.0  0.0      0     0 ?        S<   17:27   0:00 [kintegrit
root        15  0.0  0.0      0     0 ?        S<   17:27   0:00 [kblockd]
root        16  0.0  0.0      0     0 ?        S<   17:27   0:00 [ata_sff]
root        17  0.0  0.0      0     0 ?        S    17:27   0:00 [khubd]
root        18  0.0  0.0      0     0 ?        S<   17:27   0:00 [md]
root        19  0.0  0.0      0     0 ?        S    17:27   0:00 [kworker/u
root        20  0.1  0.0      0     0 ?        S    17:27   0:00 [kworker/0
root        21  0.0  0.0      0     0 ?        S    17:27   0:00 [khungtask
root        22  0.0  0.0      0     0 ?        S    17:27   0:00 [kswapd0]
root        23  0.0  0.0      0     0 ?        SN   17:27   0:00 [ksmd]
root        24  0.0  0.0      0     0 ?        S    17:27   0:00 [fsnotify_
root        25  0.0  0.0      0     0 ?        S    17:27   0:00 [ecryptfs-
root        26  0.0  0.0      0     0 ?        S<   17:27   0:00 [crypto]
root        34  0.0  0.0      0     0 ?        S<   17:27   0:00 [kthrotld]
root        37  0.0  0.0      0     0 ?        S    17:27   0:00 [scsi_eh_0
root        38  0.0  0.0      0     0 ?        S    17:27   0:00 [scsi_eh_1
root        39  0.0  0.0      0     0 ?        S    17:27   0:00 [scsi_eh_2
root        42  0.2  0.0      0     0 ?        S    17:27   0:01 [kworker/0
root        61  0.0  0.0      0     0 ?        S<   17:27   0:00 [devfreq_w
root       183  0.0  0.0      0     0 ?        S    17:27   0:00 [jbd2/sda1
root       184  0.0  0.0      0     0 ?        S<   17:27   0:00 [ext4-dio-
root       269  0.0  0.2   2816   608 ?        S    17:28   0:00 upstart-ud
root       271  0.0  0.4   3060  1204 ?        Ss   17:28   0:00 /sbin/udev
102        361  0.0  0.2   3240   648 ?        Ss   17:28   0:00 dbus-daemo
syslog     368  0.0  0.5  30020  1392 ?        Sl   17:28   0:00 rsyslogd -
root       372  0.0  0.0      0     0 ?        S<   17:28   0:00 [iprt]
root       435  0.0  0.1   2828   352 ?        S    17:28   0:00 upstart-so
root       459  0.0  0.0      0     0 ?        S<   17:28   0:00 [kpsmoused
root       509  0.0  0.2   3056   732 ?        S    17:28   0:00 /sbin/udev
root       513  0.0  0.3   3056   800 ?        S    17:28   0:00 /sbin/udev
root       531  0.0  0.0      0     0 ?        S    17:28   0:00 [flush-8:0
root       554  0.0  0.1   2908   404 ?        Ss   17:28   0:00 dhclient3 
root       576  0.0  0.9   6664  2424 ?        Ss   17:28   0:00 /usr/sbin/
root       666  0.0  0.3   4612   856 tty4     Ss+  17:28   0:00 /sbin/gett
root       669  0.0  0.3   4612   848 tty5     Ss+  17:28   0:00 /sbin/gett
root       672  0.0  0.3   4612   856 tty2     Ss+  17:28   0:00 /sbin/gett
root       674  0.0  0.3   4612   844 tty3     Ss+  17:28   0:00 /sbin/gett
root       677  0.0  0.3   4612   852 tty6     Ss+  17:28   0:00 /sbin/gett
root       682  0.0  0.3   2600   784 ?        Ss   17:28   0:00 cron
daemon     683  0.0  0.1   2452   352 ?        Ss   17:28   0:00 atd
mysql      701  0.2 13.4 317412 33392 ?        Ssl  17:28   0:00 /usr/sbin/
root       733  0.0  0.2   9092   512 ?        Sl   17:28   0:00 /usr/sbin/
root      1016  0.0  0.3   4612   848 tty1     Ss+  17:28   0:00 /sbin/gett
root      1140  0.7  1.2   9636  3096 ?        Ss   17:34   0:00 sshd: me [
me        1156  0.4  0.6   9636  1592 ?        S    17:34   0:00 sshd: me@p
me        1157  6.3  2.3   9488  5892 pts/0    Ss   17:34   0:00 -bash LANG
me        1257  0.0  0.4   4924  1168 pts/0    R+   17:34   0:00 ps auxew T
me@minibuntu:~$ exit
logout
Connection to 192.168.1.38 closed.

Script done on Sat 21 Jul 2012 05:34:37 PM WEST
 

Tuesday 19 June 2012

Converting flv to mp4

Recently, I had the need to convert a number of flash movies into mp4. I had some issues with the time needed for this operation, while using ffmpeg for this. A quick search revealed this tip:

http://www.learnosity.com/techblog/index.cfm/2010/12/29/Convert-FLV-to-MP4-with-ffmpeg-Howto

I recently needed to convert a lot of FLV files which were H264 encoded to MP4 so that they would play nice on my Mac Mini.
Initial attempts using ffmpeg were making it re-encode the entire video which would take ages and result in a larger file or worse quality.

The Solution

ffmpeg -i input.flv -vcodec copy -acodec copy output.mp4

The final comments included a question about converting multiple files but the answer did not fulfill my needs, because I had files inside a directory tree.

So I ended doing this to find all flv files and perform a quick conversion, overwriting existent files:

for file in $(find . -type f -iname *.flv -print); do \
ffmpeg -i $file -y -vcodec copy -acodec copy ${file%%.flv}.mp4; done


Monday 11 June 2012

Portable random number generator

A couple of days ago, I was asked for a way to generate random numbers within a certain range (e.g. the interval [1,10]). But there was a catch: we had an Android system with ash only and no bc.

If we had bash, we could do:
echo $[ ( $RANDOM % 10 ) + 1 ]

With ash but with bc, we could go:
echo "$RANDOM % 10 + 1" | bc

Fortunately we had awk:
echo|awk "{ print $RANDOM % 10 + 1 }"