Iomega StorCenter Pro 200rl root access

March 13th, 2009

So we got one of these NAS boxes at work and like all self respecting sysadmins we wanted root access on the box ideally with SSH, unfortunately the NAS server doesn’t support this. However it is trivial to obtain root access by using an Ubuntu live CD as follows.

Firstly boot off the live CD and once you have your live CD desktop open up a terminal window, we now need access to the system drive on the NAS box which we can acquire as follows:-

$ sudo apt-get install mdadm
$ sudo mdadm --assemble --scan
$ sudo mount /dev/md3 /mnt

Next we need to make sure we’re working on the NAS system drive for all our commands so let’s chroot into it:-

$ sudo chroot /mnt

To reset the root password we need to run:-

 # passwd

To enable SSH (which is already installed) on startup we need to run:-

# update-rc.d ssh defaults 16

Finally we cleanup and reboot the NAS server:-

# exit
$ sudo umount /mnt
$ sudo reboot

Don’t forget to remove/eject the CD when the Ubuntu live CD prompts you to.

Now once the NAS reboots into its native OS (which happens to be Debian) you’ll find you’ll be able to login to the box as root with all the power that comes with it.

Tech ,

PHP app Licensing Faux-pas

March 10th, 2009

One of the php web applications we use in the office requires a license to work, it locks its license to the hostname and ip address of the server on which it’s run.  When the license key is first entered it phones home to set the hostname and ip address on the licensing server and then stores a valid hash of the license.

We recently restructured our network and changed the ip address thus causing the app to complain the license was invalid, deleting the licensing file caused it to talk with the licensing server again but it was no use the licensing server still held the old ip address which was no longer correct. At this point I sent an e-mail off to their customer support team to get the information changed.

However, I couldn’t resist  taking a quick peek under the hood. To their credit the app is largely open source and readable except for the code that manages the license which is encrypted.  I removed the license file, fired up wireshark which logged the following conversation to their license server (anonymised to protect the guilty):-

GET /XXXXXX.php?license_key=Base64String&host_name=?Base64String&

Which generated the following reply:-


On the face of it this seems quite easy to attack given it sends the current hostname/ip to the licensing server it’d be a trivial PHP script to send back what we assume the app would want to see:-

$key = base64_decode(urldecode($_GET['license_key']));
$host = base64_decode(urldecode($_GET['host_name']));
$ip = base64_decode(urldecode($_GET['host_ip']));

echo "$key|$host|$ip";

All that remains to do is set the script up on our server, and add an entry into our /etc/hosts file so that the licensing server domain name now points at our server. Once done after removing the license file I hit refresh and surprise surprise the app accepted the license response and things continued as normal.

This is particularly weak scheme since it doesn’t even run over SSL so capturing with wireshark is trivial. The other fundamental problem is that the class which converses with the licensing server is not encrypted so that would represent another point of attack which wouldn’t require setting up a fake licensing server – just hijack the response methods.

To their credit the license key itself is validated using a hash to determine what level of features you have access to but once you’ve bought one key you are then able to apply the methods above to copy the key to as many different locations as you wish.

Any comments identifying the application in question will be removed or censored, this is not an aid to bypassing licensing requirements more a discussion of the security implications of how this particular method was implemented.

Coding , ,

Web App config files

January 21st, 2009

So like most people when I write my web applications I create a of some description and put that in the directory with the application. However, when it comes to roll out the app this causes problems due to the config differences between the live and development environments so the config file needs to be changed once the new version has been put live.

This isn’t ideal so the first obvious thing to do is to move the config file out of the web application directory to somewhere else (for example: /etc/webapp.conf). Now when a version of the web app is released you simply just have to untar the web app tarball into the correct place and everything will just work without any post-install manual tweaking.

The problem with this approach is that it doesn’t work for multi-developer environments where a developer might need to tweak the config file for a new feature they’re testing, but the web app is now looking at the /etc/webapp.conf file no matter what developer it is.

The solution I then came up with was another config file, say called which is (optionally) kept in the same directory as the web app but excluded from your version control software so it’s never checked in. Then you simple change the web app to check for this file and if it doesn’t exist load the main config file so now a developer can create a config file for just their tree. For example:-

if(file_exists(dirname(__FILE__)."/")) {
} else {

Now once we have this setup everything works and developers can change the config files if they need too (e.g. database dsn’s) and the live system can be deployed by simply untar’ing a tarball.

The next thing I noticed was if I need to add a new config file option I need to add it in all the config files, even if it’s just a system config option that won’t change no matter what environment it’s in. This is a bit of chore given I’m just a lazy developer…

So the next change I make to the config file system is to reinstate the in the web app directory with one key difference, it now has the following design pattern and it is responsible for including our main config file:-

if(file_exists(dirname(__FILE__)."/")) {
} else {

$config = array(

foreach($config as $const=>$value)
        DEFINE($const, $value);

Now this config file will first load our main web app config file (either /etc/webapp.conf or and fill in all the missing (default/system) config options that weren’t needed to be changed in the per-environment config settings. Should that need change, simply just define them and this config file will not set them.

1. Is this over the top?
2. How does everyone else handle config files?
3. Do their methods solve the issues presented above?

Coding , ,

Dead Space with Arrow Keys!

December 22nd, 2008
Dead Space with Arrow Keys

Dead Space with Arrow Keys

Having received Dead Space for my Birthday I was disappointed to find that there was no way to use the arrow keys to play especially since I’m left handed and that is far more natural to me.

However, not being one to give up at the first hurdle Google lead me this page which gives instructions for playing Dead Space with arrow keys using GlovePIE to remap the keys as you press them. It’s a good workaround but it’s simply not ideal.

The file responsible for storing your key mappings is controls.rmp located under “C:\Documents and Settings\<your username>\Local Settings\Application Data\Electronic Arts\Dead Space”, so I began examing this file, how it changed depending what the keys were set to and after an hour or two of playing about I discovered not only the offsets storing the Up/Down/Left/Right key mappings but also the correct values for the arrow keys – AND THEY WORK.

To make these changes for yourself you’ll need a hex editor like XVI32, set the following values at the following offsets in the controls.rmp file (OFFSET:VALUE):-

5C: CB
AC: D0
14C: C8
23C: CD

Now save the file and load up Dead Space, you should find you’re now able to use the arrow keys to move around. Alternatively if that’s too much like hard work you can download my pre-modified controls.rmp file below which is set to use the arrow keys – simply customise the other keys how you would like.

Download: controls.rmp.

If you’d like to use the Enter/Return key as your reload key, make the following change using XVI32:-

E8: 1C

General, Tech , ,

IWF “block” Virgin Killer wikipedia page

December 8th, 2008

So I just read that the IWF have decided to block the Virgin Killer wikipedia page for what they claim is indecent coverart. Whether it is or is not, is out of scope for this posting.

The problem is they seem to be exclusively targeting wikipedia with this block since the image is easily available from other locations not to mention peoples’ homes.

The result of the block is that due most of UK’s traffic going via the Cleanfeed content blocking system wikipedia has been forced to prevent editing articles to UK contributors because they now effectively share a few IP addresses and do not pass on the real IP address as most proxies should.

The other problem is that they have only blocked the article text and not the actual image which is still accessible from wikipedia’s servers. Infact, had they blocked the actual image to start with the editing problem may never have existed. It’s still possible to view the article text without resorting to technology like tor by using the https:// version of the site instead which ofcourse cannot be transparently filtered. The irony here is that that site renders the full article + the actual image since the actual image hasn’t been blocked.

Far more people have now seen this image on the wikipedia page than would have if this block was never attempted, this block has attracted alot of media attention causing the views to that wikipedia page to sky rocket in the past 24-48 hours.

All in all I don’t think they’ve accomplished a great deal besides drawing attention to the very image they tried to prevent people seeing by raising the profile of that image.

Update: It appears that the image on Amazon (linked above) has now been removed.

Update 2: The IWF have now decided to remove this page from their block list:-

Following representations from Wikipedia, IWF invoked its Appeals Procedure and has given careful consideration to the issues involved in this case. The procedure is now complete and has confirmed that the image in question is potentially in breach of the Protection of Children Act 1978. However, the IWF Board has today (9 December 2008) considered these findings and the contextual issues involved in this specific case and, in light of the length of time the image has existed and its wide availability, the decision has been taken to remove this webpage from our list.

IWF’s overriding objective is to minimise the availability of indecent images of children on the internet, however, on this occasion our efforts have had the opposite effect. We regret the unintended consequences for Wikipedia and its users. Wikipedia have been informed of the outcome of this procedure and IWF Board’s subsequent decision.

I suppose that’s one way to backtrack without entirely admitting you were wrong in the first place, may they carefully consider their blocks in the future lest they repeat the same mistake.

Incompetence , , ,

asterisk cdr_mysql on Ubuntu 8.04 (Hardy)

December 8th, 2008

After a successful asterisk installation I was asked to also add call recording so that calls could be monitored and reviewed.To allow easy browsing of recorded calls it’s also handy to setup CDR to store call records in a database and since MixMonitor() by records calls named after the UNIQUEID of the call it’s important this ID is recorded as well.

Unfortunately after some simple testing it seems that cdr_mysql in the asterisk-mysql package has not been compiled to log this important ID.Fortunately we can fix this ourselves using the Ubuntu packaging tools. Firstly we need to install the packages needed to edit the package:-

sudo apt-get install devscripts debhelper fakeroot pbuilder dpatch

Next we should download the source package:-

apt-get source asterisk-mysql

Now we can set about editing the package, a quick look in debian/patches tells us that this package uses dpatch to maintain its patches – so we should too:-

cd asterisk-addons-1.4.5/
dpatch-edit-patch loguniqueid

This will drop us into a sub-shell where we can make our code changes for dpatch to record for us in a patch file. All we need to do is edit the file cdr_addon_mysql.c and at around line 52 near the #define DATE_FORMAT line we should add:-


Save the file and quit out of the sub-shell created by dpatch, dpatch will now create our patch file under debian/patches/. All that’s left for us to do is edit debian/patches/00list and insert our new patch file into the list of patch files, I put mine first so the 00list file now looks like this:-


With that done we should bump the changelog to reflect our changes:-

dch -i

Add a description after the top blank * indent like “Added logging of uniqueid”, also, it’s advisable to append ~uniqueid1 (or anything you like really, the ~ is important) so that our package doesn’t conflict with any new package versions Ubuntu might release in future (Make sure that the Ubuntu codename still says “hardy” and not “intrepid” or indeed “jaunty” too). Save the changelog.

We are now ready to build our new package:-

debuild -S -uc -us

If all went well our new dsc file has been created in the parent directory, so all that remains is to get pbuilder building the package. If you’ve never used pbuilder before you need to run:-

sudo pbuilder create

If you have run pbuilder before you should check everything is up to date by running:-

sudo pbuilder update

With pbuilder up to date, let’s build our new package:-

sudo pbuilder build ../asterisk-addons_1.4.5~uniqueid1.dsc

After a bit of compiling if all was successful pbuilder will report it has successfully built the package, so let’s install it:-

sudo dpkg -i /var/cache/pbuilder/result/asterisk-mysql*.deb

Once the package is installed all that remains is to restart asterisk to pickup the new module:-

sudo asterisk -rx 'restart when convenient'

Now test your cdr_mysql logging again, you should find the uniqueid is being logged.

Linux , , , , ,

PHP, PDO & Nested Transactions

December 2nd, 2008

I’ve been using PDO as my database library and it works reasonably well (as long as you remember it’s not a full blown database abstraction library), however recently I needed to use nested transactions to ensure that the database remains consistent while doing a series of SQL statements.

Unfortunately PDO does not support nested transactions although PostgreSQL and MySQL do. I decided to extend the PDO class to support nested transactions while also using PDO to keep track of the first transaction. I came up with the following class (released under the GNU General Public License, Version 3):-

class MyPDO extends PDO {
    // Database drivers that support SAVEPOINTs.
    protected static $savepointTransactions = array("pgsql", "mysql");

    // The current transaction level.
    protected $transLevel = 0;

    protected function nestable() {
        return in_array($this->getAttribute(PDO::ATTR_DRIVER_NAME),

    public function beginTransaction() {
        if(!$this->nestable() || $this->transLevel == 0) {
        } else {
            $this->exec("SAVEPOINT LEVEL{$this->transLevel}");


    public function commit() {

        if(!$this->nestable() || $this->transLevel == 0) {
        } else {
            $this->exec("RELEASE SAVEPOINT LEVEL{$this->transLevel}");

    public function rollBack() {

        if(!$this->nestable() || $this->transLevel == 0) {
        } else {
            $this->exec("ROLLBACK TO SAVEPOINT LEVEL{$this->transLevel}");

This code will only attempt to use the SAVEPOINT code if you’re using a database driver that supports it (it should probably version check the database server) this then means that in your code you can do things like:-

$pdo = new MyPDO(DB_DSN, DB_USER, DB_PASS);
try {

    try {
    } catch(PDOException $e) {
        // If this statement fails, rollback...
        // NOTE: This will only rollback statements made in the
        //       inner try { block and not the outer one.

} catch (PDOException $e) {

NB: I’ve tweaked the code slightly when transferring it to my blog and I haven’t tested it, so there could be some minor errors – please leave comments if you spot any. Thanks!

Coding , , , ,

PHP and PDF Templates

November 26th, 2008

Recently I had to write a class that could generate PDF payslips. Going for the easy option I wanted to take the existing template to re-use it and overlay the text from the database onto the template rather than redraw the entire payslip layout (which is just simply time consuming in PHP).

My chosen PDF library is FPDF so my first attempt was to create a graphic (png/jpeg) of the existing template and use the Image() function in FPDF to add the image to the PDF. However, this didn’t work as well as I’d have hoped since the image became very blurry. I believe this is due to the image being output at 72dpi onto the PDF when it actually needs greater resolution to be usable.

Obviously a better solution was needed, enter FPDI which allows you to load a PDF file as a template. So now all I needed to do was use the payslip PDF as a template and just overlay the text onto the template. FPDI makes this extremely simple – just include the required class file and do the following:-

$pdf = new FPDI();
$count = $pdf->setSourceFile("payslip-template.pdf");
$template = $pdf->import(1, "/MediaBox");

Now all you have to do is populate your content into/over the template and output it as normal.

One caveat I did notice was that FPDI seemed to be sending the files out with the mime type “application/x-download” rather than “application/pdf” which caused my browser to not know what to do with the file if I chose to open it rather than save it. My solution was to reset the Content-type header after outputting the PDF by taking advantage of existing output buffering in my application:-

$pdf->Output("payslip.pdf", "D");
header("Content-type: application/pdf");

This works because output buffering allows us to change the headers that have already been output. If you do not currently have output buffering enabled in your code change the “ob_clean();” line to “ob_start();”.

FPDI is released under the Apache Software License, Version 2.0 which is compatible with the GNU GPL Version 3.

Coding , ,

Winter cleanup

November 25th, 2008

Well I’ve had a bit of a “winter cleanup” of my site and removed most of the pages, this site is now going to focus on just being a blog rather than being a site containing a blog.

The about me and gallery pages have gone and the links and contact pages have been rewritten to be WordPress style pages.

I also found a pretty cool theme called iNove, edited it a bit to change the header and here it is! A site redesign, looks alot better IMO. 🙂

General ,

DK2 Editor – Adding Actions to Hero Party Members PATCH

June 12th, 2008

So (quite a few years on) I started playing Dungeon Keeper 2 again – it’s still a great game and very recommended.

Having completed the single campaign I thought it’d be fun to start making my own levels, however I hit a problem in that the DK2 Editor crashes under both WinXP (and Win98 – yes, I tried it…) when trying to add an Action to a Hero Party member. This is quite annoying since if you have the Lord of the Land in a hero party you’re unable to setup some important actions, like: “Attach Portal Gem” and “Make Objective”.

Searching the newsgroup I found someone (MercAngel) who’d figured out a patch to make this work, however it didn’t work on WinXP but it did work on Win98 – but it’s tiresome to have to load up my Win98 virtual machine everytime I want to create actions under hero party members so I thought I’d look into this myself and see if I could get it to work under WinXP.

After an hour or two of poking around in OllyDbg I’d come up with something that appears to work! It resembles MercAngel’s patch in quite a few ways (so credit to him).

For ease of installation I’ve created a patch program using PatchWise which you can download from here:


It seems to work, and personally, I’d use it but it’s for you to decide if you want to use it. All I will say is that if it crashes while trying to do something different then you could use the patched DK2 Editor to add/edit hero party actions and the original unpatched one to  do everything else.

For those who are curious about what it patches, here’s the output of a binary file comparison using fc:-

C:\km\dk2edit>fc /b "DK2 Editor.exe.old" "DK2 Editor.exe"
Comparing files DK2 Editor.exe.old and DK2 EDITOR.EXE
0001B4E3: C3 83
0001B4E4: 90 F8
0001B4E5: 90 00
0001B4E6: 90 75
0001B4E7: 90 03
0001B4E8: 90 8D
0001B4E9: 90 41
0001B4EA: 90 0C
0001B4EB: 90 C3

And the difference in the assembly:-

:0041B4E0 8B410C                 mov eax, dword[ecx+0C]
:0041B4E3 C3                     ret

:0041B4E4 90 90 90 90 90 90 90 90 90 90 90 90               ............

:0041B4E0 8B410C                 mov eax, dword[ecx+0C]
:0041B4E3 83F800                 cmp eax, 000
:0041B4E6 7503                   jne 0041B4EB
:0041B4E8 8D410C                 lea eax, dword[ecx+0C]
:0041B4EB C3                     ret
:0041B4EC 90 90 90 90                                       ....

Gaming, Tech , , ,