PHP encoding and obfuscation - php

I've been trying to understand what the code below is doing. On a fundamental level I understand what the decoding process is doing however, once arriving to the for loop, It becomes a bit confusing. Basically, I'm trying to take the below and write an appropriate encoder which will allow me to reuse the decoding routine below. I'm using this for the obfuscation of a PHP script.
Would anyone be so kind as to provide assistance in the area of taking the below and providing guidance on how I'd be able to write the reverse of this (an encoder) vs the decoding method provided?
Any assistance is greatly appreciated.
<?php
$B_yhp='bCtyDEF7u+8SszsSu+kgCO5ydU+XgC8PCVdhu1jwM7cyDU6dY0V7URbSZ/';
$L_qmfd=base64_decode($B_yhp);
for($i=0; $i<strlen($L_qmfd); $i++)
{
$L_qmfd[$i]=chr(ord($L_qmfd[$i])^((91403)%256));
}
$Laz_ep=#gzinflate(strrev($L_qmfd));
//Use $Lax_ep to generate a function IE:
//create_function('$runtime',$Laz_ep);
?>
Edited:
I've tried to create the encoder using the following but I believe I'm missing / doing something wrong. The CRC values don't end up matching and the php code doesn't successfully decode to it's original state so I know I'm clearly missing a step or overlooking something here.
<?php
$hash = hash_file('crc32b', $argv[1]);
$array = unpack('N', pack('H*', $hash));
$crc32 = $array[1];
printf("CRC: %u\n",$crc32);
$content = file_get_contents($argv[1]);
$content = strrev($content);
$content = gzdeflate($content, 9);
for($i=0; $i<strlen($content); $i++)
{
$content[$i]=chr( ord($content[$i])^((91403)%256));
}
$content=base64_encode($content);
file_put_contents($argv[1]. ".packed",$content);
?>

You are doing the gzdeflate and strrev in the wrong order. Do the gzdeflate first, then reverse the deflated $content.
<?php
$hash = hash_file('crc32b', $argv[1]);
$array = unpack('N', pack('H*', $hash));
$crc32 = $array[1];
printf("CRC: %u\n",$crc32);
$content = file_get_contents($argv[1]);
$content = gzdeflate($content, 9); // Swapped these
$content = strrev($content); // two lines
for($i=0; $i<strlen($content); $i++)
{
$content[$i]=chr( ord($content[$i])^((91403)%256));
}
$content=base64_encode($content);
file_put_contents($argv[1]. ".packed",$content);
?>

Related

Regex to select div from source

A client of mine has asked for me to create a simple site that monitors files on another site. He needs to monitor the file names (unsure why?) and have them outputted to a file.
Here's the example source; http://pastebin.com/tyLUmCJr
I don't speak Russian, so I'm unaware of what the site's about. I apologize if it's anything that's 'less-than-suitable'.
Anyway, if you scroll to line 117, you will see a file name. I need to get all of the file names.
I've played around with the DOMDocument and third-party tools although I believe I could use regex to increase the speed of this. If anybody could point me in the correct direction, it would be greatly appreciated.
Note: take in mind that the source is stored within a string-variable known as $content.
Cheers!
After some more detailed, extensive research, I found a way to do it. Here's how I achieved it;
<?php
require_once("phpQuery.php");
$min = isset($_GET['min']) ? $_GET['min'] : 1;
$max = isset($_GET['max']) ? $_GET['max'] : 2;
$pages = [];
foreach(range($min, $max) as $page) {
array_push($pages, iconv("CP1251", "UTF-8", file_get_contents("http://www.fayloobmennik.net/files/list/" . $page . ".html")));
}
$html = file_get_html("http://www.fayloobmennik.net/files/list/");
$elem = $html->find('div[id=info] table > tbody', 0);
$test = $elem->find('tr a');
foreach ($test as $test2) {
$regex = '/<a href=\"([^\"]*)\">(.*)<\/a>/iU';
$test2 = preg_match($regex, $test2, $match);
print_r(iconv("CP1251", "UTF-8", $match[2]));
echo "<br/>";
}
?>
The phpQuery.php class is simple_html_dom (I believe that's what it's called?).
Cheers.

How do I choose a specific line from a file?

I'm trying to make (as immature as this sounds) an application online that prints random insults. I have a list that is 140 lines long, and I would like to print one entire line. There is mt_rand(min,max) but when I use that alongside fgets(file, "line") It doesn't give me the line of the random number, it gives me the character. Any help? I have all the code so far below.
<?php
$file = fopen("Insults.txt","r");
echo fgets($file, (mt_rand(1, 140)));
fclose($file);
?>
Try this, it's easier version of what you want to do:
$file = file('Insults.txt');
echo $file[array_rand($file)];
$lines = file("Insults.txt");
echo $lines[array_rand($lines)];
Or within a function:
function random_line($filename) {
$lines = file($filename) ;
return $lines[array_rand($lines)] ;
}
$insult = random_line("Insults.txt");
echo $insult;
use file() for this. it returns an array with the lines of the file:
$lines = file($filename);
$line = mt_rand(0, count($lines));
echo $lines[$line];
First: You totally screwed on using fgets() correctly, please refer to the manual about the meaning of the second parameter (it just plainly not what you think it is).
Second: the file() solution will work... until the filesize exceeds a certain size and exhaust the complete PHP memory. Keep in mind: file() reads the complete file into an array.
You might be better off with reading line-by-line, even if that means you'll have to discard most of the read data.
$fp = fopen(...);
$line = 129;
// read (and ignore) the first 128 lines in the file
$i = 1;
while ($i < $line) {
fgets($fp);
$i++;
}
// at last: this is the line we wanted
$theLine = fgets($fp);
(not tested!)

How does youtube encode their urls?

Quick Question
How does youtube encode theirs urls? take below
http://www.youtube.com/watch?v=MhWyAL2hKlk
what are they doing to get the value MhWyAL2hKlk
are they using some kind of encryption then decrypting at their end
I want to something similar with a website i am working on below looks horrible.
http://localhost:8888/example/account_player/?playlist=drum+and+bass+music
i would like to encode the urls to act like youtubes dont know how they do it tho.
Any advice
Well, technically speaking, YouTube generates video IDs by using an algorithm. Honestly, I have no idea. It could be a hashsum of the entire video file + a salt using the current UNIX time, or it could be a base64 encoding of something unique to the video. But I do know that it's most likely not random, because if it were, the risk of collision would be too high.
For the sake of example, though, we'll assume that YouTube does generate random ID's. Keep in mind that when using randomly generated values to store something, it is generally a good idea to implement collision checking to ensure that a new object doesn't overwrite the existing one. In practice, though, I would recommend using a hashing algorithm, since they are one-way and very effective at preventing collisions.
So, I'm not very familiar with PHP. I had to write it in JavaScript first. Then, I ported it to PHP, which turned out to be relatively simple:
function randch($charset){
return $charset[rand() % strlen($charset)];
}
function randstr($len, $charset = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-"){
$out = [];
for($i = 0; $i < $len; $i++){
array_push($out, randch($charset));
}
return join("", $out);
}
What this does is generate a random string len characters long via the given charset.
Here's some sample output:
randstr(5) -> 1EWHd
randstr(30) -> atcUVgfhAmM5bXz-3jgyRoaVnnY2jD
randstr(30, "asdfASDF") -> aFSdSAfsfSdAsSSddFFSSsdasDDaDa
Though it's not a good idea to use such a short charset.
randstr(30, "asdf")
sdadfaafsdsdfsaffsddaaafdddfad
adaaaaaafdfaadsadsdafdsfdfsadd
dfaffafaaddfdddadasaaafsfssssf
randstr(30)
r5BbvJ45HEN6dWtNZc5ZvHGLCg4Qyq
50vKb1rh66WWf9RLZQY2QrMucoNicl
Mklh3zjuRqDOnVYeEY3B0V3Moia9Dn
Now let's say you have told the page to use this function to generate a random id for a video that was just uploaded, now you want to store this key in a table with a link to the relevant data to display the right page. If an id is requested via $_GET (e.g. /watch?v=02R0-1PWdEf), you can tell the page to check this key against the database containing the video ids, and if it finds a match, grab the data from that key, else give a 404.
You can also encode directly to a base 64 string if you don't want it to be random. This can be done with base64_encode() and base64_decode(). For example, say you have the data for the video in one string $str="filename=apples.avi;owner=coolpixlol124", for whatever reason. base64_encode($str) will give you ZmlsZW5hbWU9YXBwbGVzLmF2aTtvd25lcj1jb29scGl4bG9sMTI0.
To decode it later use base64_decode($new_str), which will give back the original string.
Though, as I said before, it's probably a better idea to use a hashing algorithm like SHA.
I hope this helped.
EDIT: I forgot to mention, YouTube's video ids as of now are 11 characters long, so if you want to use the same kind of thing, you would want to use randstr(11) to generate an 11 digit random string, like this sample id I got: 6AMx8N5r6cg
EDIT 2 (2015.12.17): Completely re-wrote answer. Original was crap, I don't know what I was thinking when I wrote it.
Your question is similar to this other SO question which contains some optimised generator functions along with a clear description of the problem you're trying to solve:
php - help improve the efficiency of this youtube style url generator
It will provide you with code, a better understanding of performance issues, and a better understanding of the problem domain all at once.
Dunno how exactly google generates their strings, but the idea is really simple. Create a table like:
+----------+------------------------------+
| code | url |
+----------+------------------------------+
| asdlkasd | playlist=drum+and+bass+music |
+----------+------------------------------+
Now, create your url like:
http://localhost:8888/example/account_player/asdlkasd
After that, just read compare your own made code with the database url and load your image, video or whatever you intend to.
PS: This is just a fast example. It can be done in many other ways also of course.
If you don't want to use decimal numbers, you can encode them into base36:
echo base_convert(123456789, 10, 36); // => "21i3v9"
And decode back:
echo base_convert("21i3v9", 36, 10); // => "123456789"
function alphaID($in, $to_num = false, $pad_up = false, $pass_key = null)
{
$out = '';
$index = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$base = strlen($index);
if ($pass_key !== null) {
for ($n = 0; $n < strlen($index); $n++) {
$i[] = substr($index, $n, 1);
}
$pass_hash = hash('sha256',$pass_key);
$pass_hash = (strlen($pass_hash) < strlen($index) ? hash('sha512', $pass_key) : $pass_hash);
for ($n = 0; $n < strlen($index); $n++) {
$p[] = substr($pass_hash, $n, 1);
}
array_multisort($p, SORT_DESC, $i);
$index = implode($i);
}
if ($to_num) {
// Digital number <<-- alphabet letter code
$len = strlen($in) - 1;
for ($t = $len; $t >= 0; $t--) {
$bcp = bcpow($base, $len - $t);
$out = $out + strpos($index, substr($in, $t, 1)) * $bcp;
}
if (is_numeric($pad_up)) {
$pad_up--;
if ($pad_up > 0) {
$out -= pow($base, $pad_up);
}
}
} else {
// Digital number -->> alphabet letter code
if (is_numeric($pad_up)) {
$pad_up--;
if ($pad_up > 0) {
$in += pow($base, $pad_up);
}
}
for ($t = ($in != 0 ? floor(log($in, $base)) : 0); $t >= 0; $t--) {
$bcp = bcpow($base, $t);
$a = floor($in / $bcp) % $base;
$out = $out . substr($index, $a, 1);
$in = $in - ($a * $bcp);
}
}
return $out;
}
?>
you can encypt or decrypt using this function.
<?php
$random_id=57256;
$encode=alphaID($random_id);
$decode=alphaID($encode,true); //where boolean true reverse the string back to original
echo "Encode : {$encode} <br> Decode : {$decode}";
?>
Just visit the below for more info :
http://kvz.io/blog/2009/06/10/create-short-ids-with-php-like-youtube-or-tinyurl/
Just use an auto-increment ID value (from a database). Although I personally like the long URLs.

PHP read binary file in real binary

I searched google for my problem but found no solution.
I want to read a file and convert the buffer to binary like 10001011001011001.
If I have something like this from the file
bmoov���lmvhd�����(tF�(tF�_�
K�T��������������������������������������������#���������������������������������trak���\tkh
d����(tF�(tF������� K������������������������������������������������#������������$edts��
How can I convert all characters (including also this stuff ��) to 101010101000110010 representation??
I hope someone can help me :)
Use ord() on each byte to get its decimal value and then sprintf to print it in binary form (and force each byte to include 8 bits by padding with 0 on front).
<?php
$buffer = file_get_contents(__FILE__);
$length = filesize(__FILE__);
if (!$buffer || !$length) {
die("Reading error\n");
}
$_buffer = '';
for ($i = 0; $i < $length; $i++) {
$_buffer .= sprintf("%08b", ord($buffer[$i]));
}
var_dump($_buffer);
$ php test.php
string(2096) "00111100001111110111000001101000011100000000101000100100011000100111010101100110011001100110010101110010001000000011110100100000011001100110100101101100011001010101111101100111011001010111010001011111011000110110111101101110011101000110010101101110011101000111001100101000010111110101111101000110010010010100110001000101010111110101111100101001001110110000101000100100011011000110010101101110011001110111010001101000001000000011110100100000011001100110100101101100011001010111001101101001011110100110010100101000010111110101111101000110010010010100110001000101010111110101111100101001001110110000101000001010011010010110011000100000001010000010000100100100011000100111010101100110011001100110010101110010001000000111110001111100001000000010000100100100011011000110010101101110011001110111010001101000001010010010000001111011000010100010000000100000011001000110100101100101001010000010001001010010011001010110000101100100011010010110111001100111001000000110010101110010011100100110111101110010010111000110111000100010001010010011101100001010011111010000101000001010001001000101111101100010011101010110011001100110011001010111001000100000001111010010000000100111001001110011101100001010011001100110111101110010001000000010100000100100011010010010000000111101001000000011000000111011001000000010010001101001001000000011110000100000001001000110110001100101011011100110011101110100011010000011101100100000001001000110100100101011001010110010100100100000011110110000101000100000001000000010010001011111011000100111010101100110011001100110010101110010001000000010111000111101001000000111001101110000011100100110100101101110011101000110011000101000001000100010010100110000001110000110010000100010001011000010000001100100011001010110001101100010011010010110111000101000011011110111001001100100001010000010010001100010011101010110011001100110011001010111001001011011001001000110100101011101001010010010100100101001001110110000101001111101000010100000101001110110011000010111001001011111011001000111010101101101011100000010100000100100010111110110001001110101011001100110011001100101011100100010100100111011"
On thing you could do is to read the file into a string variable, then print the string in your binary number representation with the use of sprintfDocs:
$string = file_get_contents($file);
for($l=strlen($string), $i=0; $i<$l; $i++)
{
printf('%08b', ord($string[$i]));
}
If you're just looking for a hexadecimal representation, you can use bin2hexDocs:
echo bin2hex($string);
If you're looking for a nicer form of hexdump, please see the related question:
How can I get a hex dump of a string in PHP?
Reading a file word-wise (32 bits at once) would be faster than byte-wise:
$s = file_get_contents("filename");
foreach(unpack("L*", $s) as $n)
$buf[] = sprintf("%032b", $n);

Text to Hex conversion in php is inaccurate

I'm trying to convert a text string to hexadecimal in php (which sounds trivial enough) but all the conversions I have tried output incorrect data.
The string I need to convert is;
RTP1 •. • A ¥;¥9ÈKJ| %¯ : E~WF 3HxI#Y¥
The correct result is;
525450310120209501022e2095204120030503040ba53b03040ba539c84b041f4a7c1120202025af032020203a20457e0357462033487849230459a52020202020
But I consistently get;
52545031012020e280a201022e20e280a2204120030503040bc2a53b03040bc2a539c3884b041f4a7c1120202025c2af032020203a20457e0357462033487849230459c2a52020202020
The online calculator at http://www.swingnote.com/tools/texttohex.php works on this perfectly - I have emailed the author to request the php source code but have had no answer.
I've tried the following functions without success;
bin2hex($data);
function strToHex($string)
{
$hex='';
for ($i=0; $i < strlen($string); $i++)
{
$hex .= dechex(ord($string[$i]));
}
return $hex;
}
for ($i = 0; $i < strlen($string); $i++) {
echo dechex(ord($string[$i]));
}
and a few others I can no longer find... I'm really at a loss with this so any help will be greatly appreciated!
Thanks!
Matthew
The input string appears to contain utf-8 encoded characters (I say this based on the output). Try converting these characters back into an ASCII/ISO-8859-1 alike format.
$indat = utf8_decode("...");
$hexdata = bin2hex($indat);
I usually just process it one char at a time.
$str = 'My Cool String!';
$hex = '';
$str_ary = str_split($str);
foreach($str_ary as $char)
{
$hex .= dechex(ord($char));
}
echo $hex;
Edit:
Looking at it again, it looks like our code is very similar (didn't notice the code :\ ). I believe Jeff Parker has the right idea in the comment, it might just be a display issue.

Categories