神盾加密解密教程(一)PHP变量可用字符

前端之家收集整理的这篇文章主要介绍了神盾加密解密教程(一)PHP变量可用字符前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

先来说说PHP变量的命名规则,百度下一抓一大把:
(1) PHP的变量名区分大小写;
(2) 变量名必须以美元符号$开始;
(3) 变量名开头可以以下划线开始;
(4) 变量名不能以数字字符开头.

其实所有编程都类似的命名规范就是:
1. 变量第一个字符最好是 字母或_,不能以数字开头
2. 第二个字符开始允许 数字,字母,_

好了,差不多就是这样了,但是这不是我们要说的重点。
今天我们说说 PHP 变量的可用字符,不仅仅是 数字,字母,_ 哦。

前几天QQ上一朋友发我一个shell,是加密过的,通篇乱码,不过上面有注释,叫做 “神盾加密” 好霸气的样子。
里面用了一些比较生僻的知识点,其中最明显的就是变量名,所以今天我们先从变量开始讲。

当然网上我也没找到权威的质料强有力的说明PHP的变量名可用字符的信息,所以我只能自己测试了。(英文不好,没办法谷歌到有利的证据)
先来看下我所用的方法,(如果你有更好的方法,希望分享下。)

代码如下:
PHP
if ($_POST) {
$chr = chr($_POST['chr']);
eval('$'.$chr."=1;");
echo 'ok';
exit;
}
?>


<Meta charset="UTF-8">
test



代码还算比较简单,PHP 部分只负责解析每一个字符当作变量名的执行结果是否会抛出溢出。
比如 字符 a 那么会解析 eval('$a=1;'); 这样的结果肯定没问题,所以不会抛出异常,返回结果就是 ok 字符。
如果 字符 - 那么会解析 eval('$-=1;'); 这明显是不对的,所以会抛出 PHP Parse error: Syntax error,unexpected '-',expecting T_VARIABLE or '$' 和 ok 字符。
而下面的 ajax 部分者正是利用返回结果是否为 'ok' 而判断是否是有效的变量名。
看看执行后的结果是什么吧:

代码如下:
"\x41,\x42,\x43,\x44,\x45,\x46,\x47,\x48,\x49,\x4a,\x4b,\x4c,\x4d,\x4e,\x4f,\x50,\x51,\x52,\x53,\x54,\x55,\x56,\x57,\x58,\x59,\x5a,\x5f,\x61,\x62,\x63,\x64,\x65,\x66,\x67,\x68,\x69,\x6a,\x6b,\x6c,\x6d,\x6e,\x6f,\x70,\x71,\x72,\x73,\x74,\x75,\x76,\x77,\x78,\x79,\x7a,\x7f,\x80,\x81,\x82,\x83,\x84,\x85,\x86,\x87,\x88,\x89,\x8a,\x8b,\x8c,\x8d,\x8e,\x8f,\x90,\x91,\x92,\x93,\x94,\x95,\x96,\x97,\x98,\x99,\x9a,\x9b,\x9c,\x9d,\x9e,\x9f,\xa0,\xa1,\xa2,\xa3,\xa4,\xa5,\xa6,\xa7,\xa8,\xa9,\xaa,\xab,\xac,\xad,\xae,\xaf,\xb0,\xb1,\xb2,\xb3,\xb4,\xb5,\xb6,\xb7,\xb8,\xb9,\xba,\xbb,\xbc,\xbd,\xbe,\xbf,\xc0,\xc1,\xc2,\xc3,\xc4,\xc5,\xc6,\xc7,\xc8,\xc9,\xca,\xcb,\xcc,\xcd,\xce,\xcf,\xd0,\xd1,\xd2,\xd3,\xd4,\xd5,\xd6,\xd7,\xd8,\xd9,\xda,\xdb,\xdc,\xdd,\xde,\xdf,\xe0,\xe1,\xe2,\xe3,\xe4,\xe5,\xe6,\xe7,\xe8,\xe9,\xea,\xeb,\xec,\xed,\xee,\xef,\xf0,\xf1,\xf2,\xf3,\xf4,\xf5,\xf6,\xf7,\xf8,\xf9,\xfa,\xfb,\xfc,\xfd,\xfe,\xff"

整理后发现是这样的16进制数据,当然看不懂没关系,看下转义后的结果:

代码如下:
"A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,_,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,,?,¡,¢,£,¤,¥,¦,§,¨,©,ª,«,¬,­,®,¯,°,±,²,³,´,µ,¶,·,¸,¹,º,»,¼,½,¾,¿,À,Á,Â,Ã,Ä,Å,Æ,Ç,È,É,Ê,Ë,Ì,Í,Î,Ï,Ð,Ñ,Ò,Ó,Ô,Õ,Ö,×,Ø,Ù,Ú,Û,Ü,Ý,Þ,ß,à,á,â,ã,ä,å,æ,ç,è,é,ê,ë,ì,í,î,ï,ð,ñ,ò,ó,ô,õ,ö,÷,ø,ù,ú,û,ü,ý,þ,ÿ"

除了前面的 A-Z_a-z 是我们熟悉的,后面的那些乱七八糟的东西竟然也能当作正常的变量名,简直不可思议。
其实只是PHP拓展了变量名的字符范围,在 A-Z_a-z 之上,将变量可用字符范围拓展到了 \x7f-\xff。
所以,第一个字符范围应该是 [a-zA-Z_\x7f-\xff]
那么第二个字符是否也是这样能,我们继续测试下。
将上面 PHP 代码里的 eval('$'.$chr."=1;"); 改成 eval('$a'.$chr."=1;"); 保存测试、

代码如下:
"\x9,\xa,\xd,\x20,\x30,\x31,\x32,\x33,\x34,\x35,\x36,\x37,\x38,\x39,\x41,\xff"

发现结果多了好多字符,其实有一部分我们是要去掉的,比如 \x20 其实就是 空格,相当于 eval('$a =1;'); 而已,当然是能正常执行的。
除了空格,还有 \t\r\n 都去掉因为这些也是PHP语法说允许的 \t=\x9,\n=\xa,\r=\xd,所以我们要去掉结果中的前4个数据\x9,\x20,
最终得到的结果其实只是多了 \x30,\x39 熟悉 ascii 的人也许一眼就看出来了,这就是数字 0-9
所以第一个字符范围应该是 [\w\x7f-\xff] 对正则不熟的也许会觉得怎么不是 [0-9a-zA-Z_\x7f-\xff],其实 \w 就是 0-9a-zA-Z_

也许有人会说 $$a; ${$a}; 这样的变量呢?
我觉得这个已脱离了变量命名的范围了,不是么。

好了,关于 PHP 变量可用字符的知识点分享完毕了,如果有哪说的不对的,请留言,我会及时改正以免误导大家。

我的猜测: ascii 范围 0-127(\x00-\x7f),latin1 范围 0-255(\x00-\xff),也许PHP就是将范围扩充到 latin1 字符集了,当然我没看过PHP源码,只能说是个猜想而已。

原文链接:https://www.f2er.com/php/24602.html

猜你在找的PHP相关文章