Flabby Rabbit | The offical home of The Rabbit

Using SSI effectively

Server Side Includes (SSI) is a simple interpreted server-side scripting language. SSI is mainly used to include files inside other files, much like PHP includes.

Simple include:
File: main.html

<!--#set var="inc" value="/inc/header.inc" -->

Using variables to include files:
File: main.html

<!--#set var="inc" value="/inc/header.inc" -->
<!--#include virtual="${inc}"-->

Passing variables to create dynamic includes using SSI and JavaScript:
File: main.html

<!--#set var="inc" value="/inc/header.inc?title=Welcome" -->

File: /inc/header.inc

<script type="text/javscript">
    var title = "<!--#echo var="QUERY_STRING"-->
    alert(title);
</script>

Apache includes can also do a number of other interesting bits and pieces.

Displaying dates:

<!--#echo var="DATE_LOCAL" -->

<!-- See http://gnuplot.sourceforge.net/docs_4.2/node274.html for format specifiers -->
<!--#config timefmt="%A %B %d, %Y" -->
<!--#echo var="DATE_LOCAL" -->

Document last modified: <!--#flastmod file="index.html" -->

I have always used PHP includes in my own work but since starting my new job we do not have access to such technology and therefore have been forced to use SSI. I was wondering how the performance would differ between the two methods. There was some debate on the matter but little in the way of facts and figures. I did find one interesting point which was:

“using PHP is more efficient than using SSI because SSI is still forking a separate CGI process where PHP is not, assuming PHP is integrated as a module on the web server, not run as a CGI.”

This seemed interesting but either way any differences would be negligible and it appears no body has any definitive proof to which is faster.. Never the less there is no doubt that PHP is more powerful and flexible and for this reason I would not consider changing to SSI.

Setting default monitor for Ubuntu

When using dual screen the gnome panels automatically get attached to the default monitor. If you have something like nvidia x-config you can easily change this using their software, but what if you don’t?

Open up a new terminal window and enter:

xrandr --prop | grep "[^dis]connected" | cut --delimiter=" " -f1

This will display which devices are currently connected, now decide which one of these is the monitor you want to set to default. Now enter:

xrandr --output [monitor] --primary

Replacing [monitor] with the device you chose in the first step. Now your panels should magically move to your new default monitor.

Andrew Martin at ubuntuforums wrote a quick bash script to semi-automate this process. Copy the code below and save it with the file extension .sh. Now set this file as executable and away you go.

#!/bin/bash
# Author: Andrew Martin
# Credit: http://ubuntuforums.org/showthread.php?t=1309247
echo "Enter the primary display from the following:"            # prompt for the display
xrandr --prop | grep "[^dis]connected" | cut --delimiter=" " -f1    # query connected monitors
 
read choice                             # read the users's choice of monitor
 
xrandr --output $choice --primary                   # set the primary monitor

Creating JSON Objects with Android

After starting a new project utilizing Android and a server written in C++ I noticed that although Android has a built in JSON library there is little to no information about how to implement anything useful. The majority of responses online point users to using an additional library such as GSON. This is all well and good, but I only needed minimal functionality…converting JSON to HashMaps and vice versa.

Here is the first draft of my JSON class. With static methods to convert Map to JSONObject and the other way around, of any depth.

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.json.JSONObject;

import android.util.Log;

public class JSON {

    public static JSONObject create(Map<String, Object> params) {
        try {
           
            //Create Json
            Iterator iter = params.entrySet().iterator();
            JSONObject holder = new JSONObject();
            while(iter.hasNext()) {
                Map.Entry pairs = (Map.Entry)iter.next();
                String key = (String)pairs.getKey();
                Object v = pairs.getValue();
                if (v.getClass().equals(HashMap.class)) {
                    Map<String, Object> params2 = (Map<String, Object>)v;
                    v = create(params2);
                }
                holder.put(key, v);
            }
            return holder;
           
        } catch (Exception e) {
            StringWriter sw = new StringWriter();
            e.printStackTrace(new PrintWriter(sw));
            Log.e("JSON Error", sw.toString());
            return null;
        }
    }
}

Implementing VLC support in Java

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package vlcj;

import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFileChooser;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import uk.co.caprica.vlcj.player.MediaPlayer;

import uk.co.caprica.vlcj.player.MediaPlayerFactory;
import uk.co.caprica.vlcj.player.embedded.EmbeddedMediaPlayer;
import uk.co.caprica.vlcj.player.embedded.videosurface.CanvasVideoSurface;
import uk.co.caprica.vlcj.player.events.VideoOutputEventListener;

/**
 *
 * @author flabbyrabbit
 */
public class Main implements ActionListener {

    private final JFrame frame;
    private final JPanel contentPane;
    private final Canvas canvas;

    private final JMenuBar menuBar;
    private final JFileChooser fc = new JFileChooser();

    private final MediaPlayerFactory mediaPlayerFactory;
    private final EmbeddedMediaPlayer mediaPlayer;
    private final CanvasVideoSurface videoSurface;


    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new Main();
            }
        });
    }

    public Main() {
        canvas = new Canvas();
        canvas.setBackground(Color.black);

        contentPane = new JPanel();
        contentPane.setBackground(Color.black);
        contentPane.setLayout(new BorderLayout());
        contentPane.add(canvas, BorderLayout.CENTER);

        frame = new JFrame("MBox v0.0.1a");
        frame.setContentPane(contentPane);
        frame.setSize(800,500);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        menuBar = new JMenuBar();
        JMenu file = new JMenu("File");
        menuBar.add(file);
        JMenuItem open = new JMenuItem("Open");
        open.addActionListener(this);
        file.add(open);
        JMenuItem exit = new JMenuItem("Exit");
        exit.addActionListener(this);
        file.add(exit);
        frame.setJMenuBar(menuBar);

        mediaPlayerFactory = new MediaPlayerFactory(new String[] {"--no-video-title-show"});
        mediaPlayer = mediaPlayerFactory.newEmbeddedMediaPlayer();
        videoSurface = mediaPlayerFactory.newVideoSurface(canvas);
        mediaPlayer.setVideoSurface(videoSurface);

        mediaPlayer.addVideoOutputEventListener(new VideoOutputEventListener() {
            @Override
            public void videoOutputAvailable(MediaPlayer mp, boolean videoPlay) {
                if (videoPlay) {
                    Dimension size = mp.getVideoDimension();
                    if (size != null) {
                        canvas.setSize(size.width, size.height);
                        frame.pack();
                    }
                }
            }
        });

        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                mediaPlayer.release();
                mediaPlayerFactory.release();
            }
        });

        frame.setVisible(true);
    }

    private void open() {
        if (fc.showOpenDialog(frame) == JFileChooser.APPROVE_OPTION) {
            play(fc.getSelectedFile().toString());
        }
    }

    private void play(String location) {
        mediaPlayer.playMedia(location);
    }

    public void actionPerformed(ActionEvent e) {
        if (e.getActionCommand().equals("Open"))
            open();
        if (e.getActionCommand().equals("Exit"))
            System.exit(0);
    }

}

How to Add Bash Completion in Debian

apt-get install bash-completion

Now simply add the following to /etc/profile to enable it system wide or ~/.bash_profile for a certain user.

if [ -f /etc/bash_completion ]; then
 . /etc/bash_completion
fi

Installing ZNC (IRC Bouncer)

A BNC (short for bouncer) is a piece of software that is used to relay traffic and connections in computer networks, much like a proxy. Using a BNC allows a user to hide the original source of the user’s connection, providing privacy as well as the ability to route traffic through a specific location. A BNC can also be used to hide the true target to which a user connects.

Use of an IRC Bouncer has many of the same advantages as using irssi and screen but with the major difference of being able to use any client. An IRC Bouncer allows registered users to connect to a server which then relays this information to the target IRC server. Thus hiding the users IP address from the server, also it means that the user can be permanently logged in and the bouncer log the conversation for when the user returns.

ZNC is a fully featured BNC written in C++ and licensed under the GNU General Public License. It has support for both SSL and IPv6. Installing ZNC is very easy, being available in the app repository of most common linux distros.

sudo apt-get install znc

One thing to note for Debian Stablehttp://www.backports.org is recommended, even this is very simple. Add the following line to your sources.list found at /etc/apt/sources.list

deb http://backports.debian.org/debian-backports squeeze-backports main

then…

sudo apt-get update
sudo apt-get install znc

After it has installed correctly, we need to configure it:

znc --makeconf

Work through the questions, I installed one global module, webadmin, which allows you to control your BNC from a nice web interface. As for user modules I loaded kickrejoin and nickserv…nickserv allows the users to identify against the servers nickserv.

At the end of the instillation it would show you how to connect to your BNC:

[ ** ] To connect to this znc you need to connect to it as your irc server
[ ** ] using the port that you supplied. You have to supply your login info
[ ** ] as the irc server password like so… user:pass.
[ ** ]
[ ** ] Try something like this in your IRC client…
[ ** ] /server :

Everything should now be set up for all your IRC needs.

Using webadmin
If you have loaded webadmin, you can access your admin page at: http://example.com:8080

Change Default URL of phpMyAdmin

By default phpMyAdmin is installed at example.com/phpmyadmin. Changing this URL will make your instillation that bit more secure. To change this you need to edit the apache.conf file in the phpMyAdmin’s configuration directory. This is usually in /etc/phpmyadmin/.

At the top of this file there should be the line:

Alias /phpmyadmin /usr/share/phpmyadmin

Simply change the alias path, something like:

Alias /dblogin /usr/share/phpmyadmin

Now simply restart your apache server and you are all done:

sudo /etc/init.d/apache2 restart

Automatic Website Screenshots

I wanted to make an archive of certain sites at a regular interval. But how to get a screenshot of a website automatically?
I found this http://www.debian-administration.org/articles/413 which was almost there but not really what I was looking for. I have adapted the script to closer meet my requirements.

#!/bin/bash
SITE="http://www.hackthis.co.uk"
FILE="hackthis-$(date +%F).jpg"

vncserver :1 -geometry 1366x768 -depth 24 > /dev/null

export DISPLAY=":1"
/usr/bin/firefox --display :1 "$SITE" > /dev/null 2> /dev/null &
/bin/sleep 60
/usr/bin/import -window root -display :1 "$FILE"
killall firefox-bin

export DISPLAY=":0"
vncserver -kill :1

echo "Complete - $FILE"

Here is the result:

I plan on improving this script in a number of ways:

  1. Make firefox open in fullscreen
  2. Allow website login
  3. Remove unnecessary items from the screen

Session Fixation

A major concern regarding session security is keeping the session identifier secret. Session hijacking can only really be carried out if this is not kept secret. With a valid session identifier an attacker may find it very straight forward to gain access and impersonate users.

Obtaining valid sessions can be very simple, but there are a few simple steps to help keep your website secure. First of lets establish how am attacker can get this information:

  • Prediction
  • Capture
  • Fixation

Lets look at the first one “prediction”, this is not a practical approach and therefore you do not need to concern yourself with it to much…PHP will generate session identifiers in a VERY random way so the chance of someone simply guessing it are very thin.

Method two, “capture” this is the most common attack and I will cover this in a later post. Basically the attacker will get the victim to simply tell them there session identifier. This can be in many forms, most likely a form of XSS vulnerability , so if you are concerned look for articles on XSS and ways to combat it.

The third method is the one I am most interested in today, fixation…fixation is a way of tricking the victim into using a session identifier of your choosing. Therefore the attacker can already know the session identifier before the victim has even created it, and when they do simply and swiftly hijack their session. Example 1:

<a href="http://www.example.org/page.php?PHPSESSID=12345">Free Cattle</a>


Example

  • Bob visits http://example.org/ and checks which SID is returned. For example, the server may respond: Set-Cookie: SID=0D6441FEA4496C2.
  • Bob is now able to send Alice an e-mail: “Check out this new cool feature on our bank, http://vulnerable/?SID=0D6441FEA4496C2.”
  • Alice logs on, with fixated session identifier SID=0D6441FEA4496C2.
  • Bob changes his session to 0D6441FEA4496C2, and starts impersonating Alice.


Explanation

A standard fixation attack will have 3 steps:

  • Setup
  • Fixation
  • Entrance

First off the attacker will create a “trap-session” on the target server and obtain the session id, this will then be used as the id for the attack. This session must then be maintained (kept active) by periodically sending requests to the server using the given session. Secondly they must introduce the target to the trap-session, this will mean that when the user logs in to the target site there login will be stored in a session that the attacker knows the id of. With these steps done and the session being kept alive the attacker can come along at a later point, change his session to the trap-session and start surfing as the target.

Sorting – BubbleSort

package com.flabbyrabbit.snippets.sorting;

/**
 * Optimised bubble sort, allowing for both ascending and descending sorts.
 *
 * @author Luke Ward
 * @version 1.0
 * @category Sorting
 */

public class BubbleSort {
    public void bubbleSort(int array[]) {
        bubbleSort(array, true);
    }
   
    /**
     * Takes an array of integers and sorts them.
     *
     * @param array Array of integers to be sorted
     * @param ASC true for ascending, false for descending
     */

    public void bubbleSort(int array[], boolean ASC) {
        int j;
        boolean flag = true;
        int temp;
       
        /*
         * The use of a flag will allow the sort to stop, when no more items are being moved
         */

        while (flag) {
            flag = false;
            for(j=0; j<array.length-1; j++) {
                if ((ASC && array[j]>array[j+1]) || (!ASC && array[j]<array[j+1])) {
                    temp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = temp;
                    flag = true;
                }
            }
        }  
    }
}
 

Essentials