#1 2010-08-26 15:24:15

Mario
Member
Registered: 2010-08-08
Posts: 86

Read Ionize session data from an external script

Hey there,

not really an enhancment, but it might be useful to you.
Today I had to read some Ionize session/cookie data from an external script, which wasn't written in CI. As it tooked quite a while to extract all the Session and Decode algorithms from CI, I thought to share the code with you in case you need to do the same some time.

Note:
1. The whole Cookie will be decrypted and stored in $session.
2. The Ionize configs are included to get all the info in order to decrypt it.
3. There is no Error-Handling, you might want to include.
4. Most of the functions are from the CI base classes.
5. It's not tested enough and might be unstable. Use it at your own risk.

And here it is:

<?php
define('BASEPATH', "path/to/ionize");

include "path/to/ionize/application/config/access.php";
include "path/to/ionize/application/config/config.php";
$key = md5($config['encryption_key']);
$cookie = $config['sess_cookie_name'];
$sess_encrypt_cookie = $config['sess_encrypt_cookie'];
$session = $_COOKIE[$cookie];
// cipher and mode always seem to be the same, even though the
// CI class offers a method to change it at runtime.
$_mcrypt_cipher = "";
$_mcrypt_mode = "";
$_hash_type    = "sha1";

$_mcrypt_exists = ( ! function_exists('mcrypt_encrypt')) ? FALSE : TRUE;

if ($sess_encrypt_cookie == TRUE)
{
    $session = decode($session, $key);
}
else
{
    // encryption was not used, so we need to check the md5 hash
    $hash     = substr($session, strlen($session)-32); // get last 32 chars
    $session = substr($session, 0, strlen($session)-32);

    // Does the md5 hash match?  This is to prevent manipulation of session data in userspace
    if ($hash !==  md5($session.$key))
    {
        echo 'The session cookie data did not match what was expected. This could be a possible hacking attempt.';
        return FALSE;
    }
}

echo $session;







function mcrypt_decode($data, $key)
{
    $data = _remove_cipher_noise($data, $key);
    $init_size = mcrypt_get_iv_size(_get_cipher(), _get_mode());

    if ($init_size > strlen($data))
    {
        return FALSE;
    }

    $init_vect = substr($data, 0, $init_size);
    $data = substr($data, $init_size);
    return rtrim(mcrypt_decrypt(_get_cipher(), $key, $data, _get_mode(), $init_vect), "\0");
}
function _remove_cipher_noise($data, $key)
{
    $keyhash = _hash($key);
    $keylen = strlen($keyhash);
    $str = '';

    for ($i = 0, $j = 0, $len = strlen($data); $i < $len; ++$i, ++$j)
    {
        if ($j >= $keylen)
        {
            $j = 0;
        }

        $temp = ord($data[$i]) - ord($keyhash[$j]);

        if ($temp < 0)
        {
            $temp = $temp + 256;
        }
        
        $str .= chr($temp);
    }

    return $str;
}

function _hash($str)
{
    return ($GLOBALS["_hash_type"] == 'sha1') ? _sha1($str) : md5($str);
}

function _get_cipher()
{
    if ($GLOBALS["_mcrypt_cipher"] == '')
    {
        $GLOBALS["_mcrypt_cipher"] = MCRYPT_RIJNDAEL_256;
    }

    return $GLOBALS["_mcrypt_cipher"];
}

function _get_mode()
{
    if ($GLOBALS["_mcrypt_mode"] == '')
    {
        $GLOBALS["_mcrypt_mode"] = MCRYPT_MODE_ECB;
    }
    
    return $GLOBALS["_mcrypt_mode"];
}

function _sha1($str)
{
    if ( ! function_exists('sha1'))
    {
        if ( ! function_exists('mhash'))
        {
            require_once(BASEPATH.'libraries/Sha1.php');
            $SH = new CI_SHA;
            return $SH->generate($str);
        }
        else
        {
            return bin2hex(mhash(MHASH_SHA1, $str));
        }
    }
    else
    {
        return sha1($str);
    }
}

function _xor_decode($string, $key)
{
    $string = _xor_merge($string, $key);

    $dec = '';
    for ($i = 0; $i < strlen($string); $i++)
    {
        $dec .= (substr($string, $i++, 1) ^ substr($string, $i, 1));
    }

    return $dec;
}

function _xor_merge($string, $key)
{
    $hash = _hash($key);
    $str = '';
    for ($i = 0; $i < strlen($string); $i++)
    {
        $str .= substr($string, $i, 1) ^ substr($hash, ($i % strlen($hash)), 1);
    }

    return $str;
}

function decode($string, $key)
{
    if (preg_match('/[^a-zA-Z0-9\/\+=]/', $string))
    {
        return FALSE;
    }

    $dec = base64_decode($string);

    if ($GLOBALS["_mcrypt_exists"] === TRUE)
    {
        if (($dec = mcrypt_decode($dec, $GLOBALS["key"])) === FALSE)
        {
            return FALSE;
        }
    }

    return _xor_decode($dec, $key);
}

?>

Regards,
Mario

Offline

#2 2010-08-26 17:06:05

Michel-Ange
Ionize Core Team
From: Paris, France
Registered: 2010-03-22
Posts: 927
Website

Re: Read Ionize session data from an external script

Great work !

Maybe we will integrate this in all external app ionize needs to use ?


Inspiration & Innovation : Websites by Partikule, Agence Web Paris

Offline

#3 2010-08-26 17:24:21

Mario
Member
Registered: 2010-08-08
Posts: 86

Re: Read Ionize session data from an external script

In general, this should work. But usually I'm careful with including files from external scripts (like config files in this case). They might change or move. But in general, this should work for all apps (as long as they're located at the same domain, of course).
The code is a bit messed up. One should clean it up and shorten it a bit, before using it.

Last edited by Mario (2010-08-26 17:25:07)

Offline

#4 2010-08-26 17:37:39

Michel-Ange
Ionize Core Team
From: Paris, France
Registered: 2010-03-22
Posts: 927
Website

Re: Read Ionize session data from an external script

About including Ionize config files from external scripts :

I generally add in the external script folder a dedicated config file, which build the path to Ionize.
This script is called from the standard external script config file.

So if we decide to implement a new version of the external script, we just have to add our require to the existing config file of this script.

Have a look at the tinyBrowser integration : The config file "config_tinybrowser.php" includes the dedicated "config.ionize.php" file, which contains :

$base_url = ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == "on") ? "https" : "http");
$base_url .= "://".$_SERVER['HTTP_HOST'];
$base_url .= str_replace(basename($_SERVER['SCRIPT_NAME']),"",$_SERVER['SCRIPT_NAME']);  
$base_url = substr($base_url, 0, strpos($base_url, 'themes'));
...

// and other great things....

Inspiration & Innovation : Websites by Partikule, Agence Web Paris

Offline

What's Ionize ?

Ionize is an Open Source Content Management System created by webdesigners for webdesigners.

Created and maintained by Partikule and Toopixel, Ionize wants to be the easiest and most powerful CMS.

Can I help ?

Because talent is nothing without involvement, we are looking for motivated coders and webdesigners to join the project team.

Resources

Website : ionizecms.com
Documentation : doc.ionizecms.com

Development : Ionize on GitHub
Translations : Ionize Translations