Earlier quoted context omitted.
It's an XOR encryption, with a largish key - 12 bytes if I make the old hacker news comment correctly. If you do the standard known-text XOR key finding algorithm, you need a 24-byte known text. That's some brute forcing, if you ask me.
But you're just looking for the text being in a certain range of characters. The first stage is determining the key length, you can do this by looking at the number of different character values in positions 1,2,3... then 1,3,5,... and 2,4,6,... then 1,4,7,... etc. keylength=1 127 keylength=2 114 116 keylength=3 107 102 106 keylength=4 78 94 98 103 keylength=5 111 118 115 114 119 keylength=6 81 71 81 77 79 77 keyleng…
$ ./4.pl 12 "function"
POS: 0: S->78 T->71 U->69
POS: 1: j->76 l->64 m->59
POS: 2: L->73 J->67 W->64
POS: 3: V->65 Q->55 P->49
POS: 4: m->68 v->50 `->49
POS: 5: E->54 C->52 O->48
POS: 6: 6->57 0->56 1->56
POS: 7: u->56 t->54 x->50
POS: 8: k->76 l->70 m->66
POS: 9: R->69 U->57 H->51
POS: 10: _->69 Y->62 ^->54
POS: 11: j->70 m->59 l->55
Note that the correct key in each position is usually either the first or second possibility, but there are some times when it isn't there at all.(It's better if you give it a longer string, if I give it "function " with the trailing space then it gets 9/12 as the most popular, 2/12 as second most popular and the remaining one as the third most popular. There are even better choices, see below, but I chose to go with this as it helps show how to continue with non-perfect information).
Next I knocked up a quick program to allow me to try different keys to decrypt it, it prints out the code in blocks of the appropriate keylength so it's easy to see if a specific character position is correct or not. The program takes various commands from stdin (k = print key, S = set key, s = set individual key character, p = print in keylength sized blocks, P = print entire decrypted block):-
$ ./5.pl 12
k
key is aaaaaaaaaaaa
S SjLVmE6ukR_j
key is now SjLVmE6ukR_j
p
/)abjutt uy
stcm&vauiadl
es\12i`(!Gisue
t("_UERQER/)
{$YCIOKNE= $
HTRPYCOHKIC_
VATS=$_WOSR=
&$NTRP_WOSR_
VATS=$_@ET;&
$HRTV_GBT_PA
RS=}\12//cie&w
itn crrhr
`u
ncriin \127_doe
($k)}@hbadcr
('NTRP/6.1&5
...
Getting there, but still a way off. There are a few strings like COIKOE[#n]= which could be COOKIE, so we fiddle with the 3rd column and see some interesting things in the output:- s 2 J
p
...
elseof(oasYp
...
COOKOE[#n]=
...
systcm(#c)=}
...
Neither of the other two choices for column 4 produce the right string, but it's simple enough to find the ciphertext and find what is needed to make elseof -> elseif, COOKOE -> COOKIE and systcm -> system. It's k:- s 4 k
k
key is SjJVkE6ukR_j
p
...
elseif(oasYp
...
COOKIE[#n]=
...
system(#c)=}
We carry on doing this based on more clues like this (it gets easier and easier!) and we end up with:- k
key is SjJVkE6rkRYj
p
//adjust sy
stem variabl
es
if(!@isse
t($_SERVER))
{$_COOKIE=&$
HTTP_COOKIE_
VARS;$_POST=
...
And printing out the entire decrypted buffer without extra linebreaks every 12 chars gives:- P
//adjust system variables
if(!@isset($_SERVER)){$_COOKIE=&$HTTP_COOKIE_VARS;$_POST=&$HTTP_POST_VARS;$_GET=&$HTTP_GET_VARS;}
//die with error
function x_die($m){@header('HTTP/1.1 500 '.$m);@die();}
//check if we can exec
define('has_passthru',@function_exists('passthru'));
define('has_system',@function_exists('system'));
define('has_shell_exec',@function_exists('shell_exec'));
define('has_popen',@function_exists('popen'));
...
Interestingly, trying known plaintext of "define" gives us the entire key as the most probably choice first time:- $ ./4.pl 12 "define"
POS: 0: S->75 X->56 _->54
POS: 1: j->77 a->51 f->47
POS: 2: J->71 A->55 F->49
POS: 3: V->61 ]->44 Z->43
POS: 4: k->59 h->43 *->40
POS: 5: E->55 8->48 4->44
POS: 6: 6->52 w->47 43
POS: 7: r->55 d->43 s->40
POS: 8: k->75 `->51 g->51
POS: 9: R->59 Y->55 X->49
POS: 10: Y->69 R->49 U->47
POS: 11: j->61 `->43 m->42