~ overflow ~

Author Archive

Hacking eval and base64 php “encrypt”

by z3n on Nov.17, 2010, under Coding

Problem:

There are some paranoid coders that nest many eval + base64 one inside the other in order to protect the code. This is not a real ecrypt method, just a lame way to avoid users from removing the annyoing banner by the cost or overloading the server.

example of this type of scheme:

<?php eval(gzinflate(base64_decode('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'))); ?>

Solution:

I wrote a little function for this before, to break reviewitonline.net’s “protection”. Now i have a full class with better handling and able to decode subfolders.

There you go:

<?php

// (c) z3n - R1V1@100503 - www.overflow.biz - rodrigo.orph@gmail.com

class eval_hack {
	protected $temp;
	protected $dest;

	protected $tdir = array();
	protected $tfile = array();

	protected $ext = array("php");

	public function __construct($folder, $temp = "temp/", $dest = "decoded/") {

		$this->o("(c) z3n - R1V1@100503 - www.overflow.biz - rodrigo.orph@gmail.com");

		$this->temp = $temp;
		$this->dest = $dest;

		if ($this->check())
			$this->process($folder);

	}

	protected function check() {
		if (file_exists($this->temp) && is_writable($this->temp)) {
			if (file_exists($this->dest) && is_writable($this->dest)) {
				return true;
			} else {
				$this->o("Destination path (".$this->dest.") is not writable / don't exists");
			}
		} else {
			$this->o("Temp path (".$this->temp.") is not writable / don't exists");
		}

		return false;
	}

	protected function save($fn, $content) {
		$fn = $this->dest . $fn;
		@ mkdir (dirname($fn), 0777, true);
		return file_put_contents($fn, $content);
	}

	protected function process($folder) {
		if (file_exists($folder) && is_readable($folder)) {
			for ($this->tdir[0] = $folder, $i = 0;$i < count($this->tdir);$i++) {
				$this->o("Processing: ".$this->tdir[$i]."...");
				$this->rddir($this->tdir[$i]);

				for ($j = 0,$k = count($this->tfile), $this->o("Found: ".$k." files");$j < $k;$j++) {
					$fn = $this->tdir[$i] . "/" . $this->tfile[$j];
					if (file_exists($fn) && !is_dir($fn) && filesize($fn) > 0) {
						$ext = strtolower(substr($fn,strrpos($fn,".")-strlen($fn)+1));
						if (in_array($ext,$this->ext)) {
							$this->o("Decoding: ".$fn);
							$str = $this->decode(file_get_contents($fn));
							if ($str === false) {
								$this->o("Error decoding: ".$fn);
							} else { // save file to new path
								$this->save($fn, $str);
							}
						}
					} elseif (is_dir($fn) && $this->tfile[$j] != "." && $this->tfile[$j] != "..") {
						$this->tdir[] = $fn;
					}
				}

				$this->tfile = array();
			}

		} else {
			$this->o("Process path (".$folder.") is invalid");
		}
	}

	protected function rddir($dir) { /* v2.17-OO */
		if (is_dir($dir)) {
			if ($dh = opendir($dir)) {
				while (($file = readdir($dh)) !== false) {
					if ($file != "." && $file != "..") {
						if (is_dir($dir . $file))
							$this->tdir[] = $dir . $file;
						else
							$this->tfile[] = $file;
					}
				}
				closedir($dh);
			}
		}
	}

	public function decode($x, $cut_crap = true) {
		/**
		 * @param $x string with the file
		 * @return false | string
		 */

		for ($i = 0;strpos($x,"eval(") !== false;$i++) {
			$this->o(".", false);
			file_put_contents($this->temp . "x" . $i . ".php",str_replace("eval(","file_put_contents('".$this->temp."y".$i.".php',",$x));
			exec("php ".$this->temp."x".$i.".php");
			unlink($this->temp . "x".$i.".php");
			if ($i > 0)
				unlink($this->temp . "y".($i - 1).".php");

			$x = file_get_contents($this->temp . "y".$i.".php");
		}

		$this->o($i . " nested");

		if (file_exists($this->temp . "y". ($i - 1).".php")) {
			unlink($this->temp . "y" . ($i - 1) . ".php");

			if ($cut_crap) {
				if (substr($x, 0, 7) == "?><?php")
					$x = substr($x, 2);

				if (substr($x, -4) == "?><?")
					$x = substr($x, 0, -4);
			}

			return $x;
		} else {
			return false;
		}
	}

	private function o($msg, $nl = true) {
		echo $msg.($nl ? "\n" : "");
	}

}

if (php_sapi_name() != "cli")
	die("You must run this on CLI");

if (!isset($argv[1]))
	die("Usage: ".$_SERVER['PHP_SELF']." <folder/to/hack/> [temp folder] [destination folder]");

$hack = new eval_hack($argv[1], isset($argv[2]) ? $argv[2] : "temp/", isset($argv[3]) ? $argv[3] : "decoded/");

?>

As for the people who really want to protect their code, you might want to have it on zend or ioncube, although they are also engineering reverible, just a bit harder.

Leave a Comment :, , , , more...

rsync over ssh with custom port

by z3n on Oct.29, 2010, under Linux Happyness

Problem:

How to do a rsync with custom ssh port ?

Solution:

This was a bit hard to find, so i’m posting it.
add:
-e “ssh -p PORT_NUMBER -C -oCompressionLevel=9″

to the command, like this:

rsync -azv --bwlimit=400 -e "ssh -p 12345 -C -oCompressionLevel=9" YOUR_HAPPY_USER@YOUR_SERVER:/path/to/files/from/server /path/to/local

Source:

mostly code

Leave a Comment :, , more...

label for=”id” don’t work on IE

by z3n on Sep.27, 2010, under Coding, Tips & Hints

Problem:

<input type='radio' value='x' id='something_1' name='something'>
<label for='something_1'>cool label</label>

When user clicks on the label radio should be selected, this only happens on firefox.

Solution:

$("label").click(function(){
	if ($(this).attr("for") != "")
		$("#" + $(this).attr("for")).click();
});

More info on this issue:

Stackoverflow posting

Leave a Comment :, , , , , more...

jQuery Validator scrollTo snippet

by z3n on Sep.26, 2010, under Coding, Tips & Hints

Problem:

How to automatically scroll to the first wrong input on a long form validated using jquery validator?

Solution:

invalidHandler: function(form,validator) {
	if (validator.numberOfInvalids())
		setTimeout(function(){
			$.scrollTo($("form_id").(":input.error:first"), 500);
		},250);
}
Leave a Comment :, , , more...

Disable local email delivery on hosted domains

by z3n on Sep.04, 2010, under Linux Happyness

Problem:

There’s some domains on a server that users a external server to process the emails (eg. google servers, aspmx.l.google.com) those emails are all fine when sent from outside the box but when sent from the box they fail to reach the destination or get delivered to a local user.

Solution:

define(`MAIL_HUB', `example.com.')dnl
define(`LOCAL_RELAY', `example.com.')dnl

For sendmail, this will make the domain’s emails to be delivered to the ip address assigned at the domain’s MX record.

Note:

This seemed promising for me at first look, but it will redirect ALL local domains to this MX record, ruining everything. Nothing new when dealing with sendmail, anyway when i find a better solution for this i will update this post again.

Source:

ServerFault

Leave a Comment :, , , more...

Itaú shopline class

by z3n on Sep.03, 2010, under Coding

Problema:

A integração PHP proposta pelo Itaú é desastrosa, uma classe compilada em Java que requer um módulo beta descontinuado em PHP.

Solução:

Utilizando engenharia reversa descompilei a classe:

package Itau;

public class Itaucripto
{

    public Itaucripto()
    {
        CHAVE_ITAU = "SEGUNDA12345ITAU";
        TAM_COD_EMP = 26;
        TAM_CHAVE = 16;
        numbers = "0123456789";
        sbox = new int[256];
        key = new int[256];
        numPed = "";
        tipPag = "";
        codEmp = "";
    }

    private String Algoritmo(String s, String s1)
    {
        int k = 0;
        int l = 0;
        String s2 = "";
        Inicializa(s1);
        for(int j = 1; j <= s.length(); j++)
        {
            k = (k + 1) % 256;
            l = (l + sbox[k]) % 256;
            int i = sbox[k];
            sbox[k] = sbox[l];
            sbox[l] = i;
            int i1 = sbox[(sbox[k] + sbox[l]) % 256];
            int j1 = s.charAt(j - 1) ^ i1;
            s2 = s2 + (char)j1;
        }

        return s2;
    }

    private String PreencheBranco(String s, int i)
    {
        String s1;
        for(s1 = s.toString(); s1.length() < i; s1 = s1 + " ");
        return s1.substring(0, i);
    }

    private String PreencheZero(String s, int i)
    {
        String s1;
        for(s1 = s.toString(); s1.length() < i; s1 = "0" + s1);
        return s1.substring(0, i);
    }

    private void Inicializa(String s)
    {
        int i1 = s.length();
        for(int j = 0; j <= 255; j++)
        {
            key[j] = s.charAt(j % i1);
            sbox[j] = j;
        }

        int l = 0;
        for(int k = 0; k <= 255; k++)
        {
            l = (l + sbox[k] + key[k]) % 256;
            int i = sbox[k];
            sbox[k] = sbox[l];
            sbox[l] = i;
        }

    }

    private boolean isNumeric(String s)
    {
        if(s.length() > 1)
        {
            boolean flag = true;
            for(int i = 0; i < s.length(); i++)
            {
                flag = isNumeric(s.substring(i, i + 1));
                if(!flag)
                    return flag;
            }

            return flag;
        }
        return numbers.indexOf(s) >= 0;
    }

    private String Converte(String s)
    {
        char c2 = (char)(int)(26D * Math.random() + 65D);
        String s1 = "" + c2;
        for(int i = 0; i < s.length(); i++)
        {
            char c1 = s.charAt(i);
            char c = c1;
            s1 = s1 + Integer.toString(c);
            char c3 = (char)(int)(26D * Math.random() + 65D);
            s1 = s1 + c3;
        }

        return s1;
    }

    private String Desconverte(String s)
    {
        String s1 = "";
        for(int i = 0; i < s.length(); i++)
        {
            String s2 = "";
            for(char c = s.charAt(i); Character.isDigit(c); c = s.charAt(i))
            {
                s2 = s2 + s.charAt(i);
                i++;
            }

            if(s2.compareTo("") != 0)
            {
                int j = Integer.parseInt(s2);
                s1 = s1 + (char)j;
            }
        }

        return s1;
    }

    public String geraDados(String s, String s1, String s2, String s3, String s4, String s5, String s6,
            String s7, String s8, String s9, String s10, String s11, String s12, String s13,
            String s14, String s15, String s16, String s17)
    {
        s = s.toUpperCase();
        s4 = s4.toUpperCase();
        if(s.length() != TAM_COD_EMP)
            return "Erro: tamanho do codigo da empresa diferente de 26 posi\347\365es.";
        if(s4.length() != TAM_CHAVE)
            return "Erro: tamanho da chave da chave diferente de 16 posi\347\365es.";
        if(s1.length() < 1 || s1.length() > 8)
            return "Erro: n\372mero do pedido inv\341lido.";
        if(isNumeric(s1))
            s1 = PreencheZero(s1, 8);
        else
            return "Erro: numero do pedido n\343o \351 num\351rico.";
        if(s2.length() < 1 || s2.length() > 11)
            return "Erro: valor da compra inv\341lido.";
        int i = s2.indexOf(',');
        if(i != -1)
        {
            String s20 = s2.substring(i + 1);
            if(!isNumeric(s20))
                return "Erro: valor decimal n\343o \351 num\351rico.";
            if(s20.length() != 2)
                return "Erro: valor decimal da compra deve possuir 2 posi\347\365es ap\363s a virgula.";
            s2 = s2.substring(0, s2.length() - 3) + s20;
        } else
        {
            if(!isNumeric(s2))
                return "Erro: valor da compra n\343o \351 num\351rico.";
            if(s2.length() > 8)
                return "Erro: valor da compra deve possuir no m\341ximo 8 posi\347\365es antes da virgula.";
            s2 = s2 + "00";
        }
        s2 = PreencheZero(s2, 10);
        s6 = s6.trim();
        if(s6.compareTo("02") != 0 && s6.compareTo("01") != 0 && s6.compareTo("") != 0)
            return "Erro: c\363digo de inscri\347\343o inv\341lido.";
        if(s7.compareTo("") != 0 && !isNumeric(s7) && s7.length() > 14)
            return "Erro: n\372mero de inscri\347\343o inv\341lido.";
        if(s10.compareTo("") != 0 && (!isNumeric(s10) || s10.length() != 8))
            return "Erro: cep inv\341lido.";
        if(s13.compareTo("") != 0 && (!isNumeric(s13) || s13.length() != 8))
            return "Erro: data de vencimento inv\341lida.";
        if(s15.length() > 60)
            return "Erro: observa\347\343o adicional 1 inv\341lida.";
        if(s16.length() > 60)
            return "Erro: observa\347\343o adicional 2 inv\341lida.";
        if(s17.length() > 60)
        {
            return "Erro: observa\347\343o adicional 3 inv\341lida.";
        } else
        {
            s3 = PreencheBranco(s3, 40);
            s5 = PreencheBranco(s5, 30);
            s6 = PreencheBranco(s6, 2);
            s7 = PreencheBranco(s7, 14);
            s8 = PreencheBranco(s8, 40);
            s9 = PreencheBranco(s9, 15);
            s10 = PreencheBranco(s10, 8);
            s11 = PreencheBranco(s11, 15);
            s12 = PreencheBranco(s12, 2);
            s13 = PreencheBranco(s13, 8);
            s14 = PreencheBranco(s14, 60);
            s15 = PreencheBranco(s15, 60);
            s16 = PreencheBranco(s16, 60);
            s17 = PreencheBranco(s17, 60);
            String s18 = Algoritmo(s1 + s2 + s3 + s5 + s6 + s7 + s8 + s9 + s10 + s11 + s12 + s13 + s14 + s15 + s16 + s17, s4);
            String s19 = Algoritmo(s + s18, CHAVE_ITAU);
            return Converte(s19);
        }
    }

    public String geraCripto(String s, String s1, String s2)
    {
        if(s.length() != TAM_COD_EMP)
            return "Erro: tamanho do codigo da empresa diferente de 26 posi\347\365es.";
        if(s2.length() != TAM_CHAVE)
            return "Erro: tamanho da chave da chave diferente de 16 posi\347\365es.";
        s1 = s1.trim();
        if(s1.compareTo("") == 0)
        {
            return "Erro: c\363digo do sacado inv\341lido.";
        } else
        {
            String s3 = Algoritmo(s1, s2);
            String s4 = Algoritmo(s + s3, CHAVE_ITAU);
            return Converte(s4);
        }
    }

    public String geraConsulta(String s, String s1, String s2, String s3)
    {
        if(s.length() != TAM_COD_EMP)
            return "Erro: tamanho do codigo da empresa diferente de 26 posi\347\365es.";
        if(s3.length() != TAM_CHAVE)
            return "Erro: tamanho da chave da chave diferente de 16 posi\347\365es.";
        if(s1.length() < 1 || s1.length() > 8)
            return "Erro: n\372mero do pedido inv\341lido.";
        if(isNumeric(s1))
            s1 = PreencheZero(s1, 8);
        else
            return "Erro: numero do pedido n\343o \351 num\351rico.";
        if(s2.compareTo("0") != 0 && s2.compareTo("1") != 0)
        {
            return "Erro: formato inv\341lido.";
        } else
        {
            String s4 = Algoritmo(s1 + s2, s3);
            String s5 = Algoritmo(s + s4, CHAVE_ITAU);
            return Converte(s5);
        }
    }

    public String decripto(String s, String s1)
    {
        s = Desconverte(s);
        String s2 = Algoritmo(s, s1);
        codEmp = s2.substring(0, 26);
        numPed = s2.substring(26, 34);
        tipPag = s2.substring(34, 36);
        return s2;
    }

    public String retornaCodEmp()
    {
        return codEmp;
    }

    public String retornaPedido()
    {
        return numPed;
    }

    public String retornaTipPag()
    {
        return tipPag;
    }

    public String geraDadosGenerico(String s, String s1, String s2)
    {
        s = s.toUpperCase();
        s2 = s2.toUpperCase();
        if(s.length() != TAM_COD_EMP)
            return "Erro: tamanho do codigo da empresa diferente de 26 posi\347\365es.";
        if(s2.length() != TAM_CHAVE)
            return "Erro: tamanho da chave da chave diferente de 16 posi\347\365es.";
        if(s1.length() < 1)
        {
            return "Erro: sem dados.";
        } else
        {
            String s3 = Algoritmo(s1, s2);
            String s4 = Algoritmo(s + s3, CHAVE_ITAU);
            return Converte(s4);
        }
    }

    private int sbox[];
    private int key[];
    private String codEmp;
    private String numPed;
    private String tipPag;
    private String CHAVE_ITAU;
    private int TAM_COD_EMP;
    private int TAM_CHAVE;
    private String dados;
    public String numbers;
}

Nada satisfatório, mas é melhor do que utilizar o módulo java beta ou a integração windows emulada no linux.

Também achei um port em PHP, não é uma maravilha, mas dá pro gasto por enquanto.

7 Comments :, , , , , more...

preg (regular expression) to get emails in php

by z3n on Aug.28, 2010, under Coding

Problem:

A regular experssion pattern for getting emails on a random string.

Solution:

preg_match_all(
	"/[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}/i",
	$string,
	$matches,
	PREG_PATTERN_ORDER
);
Leave a Comment :, , , more...

.htaccess to redirect root to folder

by z3n on Aug.04, 2010, under Coding, Tips & Hints

Problem:

How to do a 302/permanent SEO compliant redirect from a root folder to somewhere else?

Solution:

RedirectMatch permanent ^/$ http://mydomain.com/php/index.php

Source:

digitalpoint

Leave a Comment :, , , more...

A worthless milestone

by z3n on Jul.28, 2010, under lol

So today i’ve finally reached 100k spam emails on my gmail account, hurray!

Leave a Comment :, , more...

BBCode php parser class

by z3n on Jul.10, 2010, under Coding, Tips & Hints

This class is based on jquery’s markitup plugin function, i did some code compressions and added youtube handler to it. If you need base_defines function, just search the site.

class BBCodeParser {
	private $text;

	public function __construct() {
		base_defines(array(
			"EMOTICONS_DIR" => "/img/emoticons/"
		));
	}

	public function escape($s) {
		$this->text = strip_tags($this->text);
		$code = $s[1];
		$code = htmlspecialchars($code);
		$code = str_replace("[", "&#91;", $code);
		$code = str_replace("]", "&#93;", $code);
		return '<pre><code>'.$code.'</code></pre>';
	}	

	public function removeBr($s) {
		return str_replace("<br />", "", $s[0]);
	}

	public function parse($text) {
		$this->text = trim($text);
		$this->text = preg_replace(array(
				'/\[b\](.*?)\[\/b\]/ms',
				'/\[i\](.*?)\[\/i\]/ms',
				'/\[u\](.*?)\[\/u\]/ms',
				'/\[img\](.*?)\[\/img\]/ms',
				'/\[email\](.*?)\[\/email\]/ms',
				'/\[url\="?(.*?)"?\](.*?)\[\/url\]/ms',
				'/\[size\="?(.*?)"?\](.*?)\[\/size\]/ms',
				'/\[youtube\](.*?)\[\/youtube\]/ms',
				'/\[color\="?(.*?)"?\](.*?)\[\/color\]/ms',
				'/\[quote](.*?)\[\/quote\]/ms',
				'/\[list\=(.*?)\](.*?)\[\/list\]/ms',
				'/\[list\](.*?)\[\/list\]/ms',
				'/\[\*\]\s?(.*?)\n/ms'
			),array(
				'<strong>\1</strong>',
				'<em>\1</em>',
				'<u>\1</u>',
				'<img src="\1" alt="\1" />',
				'<a href="mailto:\1">\1</a>',
				'<a href="\1">\2</a>',
				'<span style="font-size:\1%">\2</span>',
				'<object width="450" height="350"><param name="movie" value="\1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="\1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="450" height="350"></embed></object>',
				'<span style="color:\1">\2</span>',
				'<blockquote>\1</blockquote>',
				'<ol start="\1">\2</ol>',
				'<ul>\1</ul>',
				'<li>\1</li>'
			),
			str_replace(array(
					':)',
					':D',
					':o',
					':p',
					':P',
					':(',
					';)'
				),array(
					'<img alt=":)" src="'.EMOTICONS_DIR.'emoticon-happy.png" />',
					'<img alt=":D" src="'.EMOTICONS_DIR.'emoticon-smile.png" />',
					'<img alt=":o" src="'.EMOTICONS_DIR.'emoticon-surprised.png" />',
					'<img alt=":p" src="'.EMOTICONS_DIR.'emoticon-tongue.png" />',
					'<img alt=":P" src="'.EMOTICONS_DIR.'emoticon-tongue.png" />',
					'<img alt=":(" src="'.EMOTICONS_DIR.'emoticon-unhappy.png" />',
					'<img alt=";)" src="'.EMOTICONS_DIR.'emoticon-wink.png" />'
				),
				preg_replace_callback(
					'/\[code\](.*?)\[\/code\]/ms',
					array(&$this, "escape"), // http://www.php.net/manual/en/function.preg-replace-callback.php#90849
					//"BBCodeParser::escape", // http://www.php.net/manual/en/function.preg-replace-callback.php#92548
					$this->text
				)
			)
		);

		// paragraphs
		$this->text = str_replace("\r", "", $this->text);
		$this->text = "<p>".preg_replace("/(\n){2,}/", "</p><p>", $this->text)."</p>";
		$this->text = nl2br($this->text);

		// clean some tags to remain strict
		// not very elegant, but it works. No time to do better ;)

		$this->text = preg_replace_callback('/<pre>(.*?)<\/pre>/ms', array(&$this,"removeBr"), $this->text);
		$this->text = preg_replace('/<p><pre>(.*?)<\/pre><\/p>/ms', "<pre>\\1</pre>", $this->text);

		$this->text = preg_replace_callback('/<ul>(.*?)<\/ul>/ms', array(&$this,"removeBr"), $this->text);
		$this->text = preg_replace('/<p><ul>(.*?)<\/ul><\/p>/ms', "<ul>\\1</ul>", $this->text);

		return $this->text;
	}
}
1 Comment :, , , more...

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!