- [1. GPC等转义的绕过](#1-gpc等转义的绕过)
- [1.1. 编码转换问题](#11-编码转换问题)
- [2. 神奇的字符串](#2-神奇的字符串)
- [2.1. 字符处理函数报错信息泄露](#21-字符处理函数报错信息泄露)
- [2.2. iconv函数字符编码转换截断](#22-iconv函数字符编码转换截断)
- [3. php://输入输出流](#3-php输入输出流)
- [3.1. php://input](#31-phpinput)
- [3.2. php://output和php://filter](#32-phpoutput和phpfilter)
- [3.2.1. php://filter写文件](#321-phpfilter写文件)
- [3.2.2. php://filter读文件](#322-phpfilter读文件)
- [4. PHP代码解析标签](#4-php代码解析标签)
- [5. fuzz漏洞发现](#5-fuzz漏洞发现)
- [6. 不严谨的正则表达式](#6-不严谨的正则表达式)
- [6.1. 没有使用^和$限定匹配开始/结束位置](#61-没有使用和限定匹配开始结束位置)
- [6.2. 特殊字符未转义](#62-特殊字符未转义)
- [7. 十余种MySQL报错注入](#7-十余种mysql报错注入)
- [8. Windows FindFirstFile 利用](#8-windows-findfirstfile-利用)
- [9. PHP可变变量](#9-php可变变量)
转义绕过、字符串常见的安全问题、PHP输入输出流、FUZZ挖掘漏洞以及正则表达式不严谨。
# 1. GPC等转义的绕过
- GPC会自动把提交上去的单引号等敏感字符给转义掉
- 在PHP5之后用$_SERVER取到的header字段不受GPC影响
- 在header注入里面最常见的是user-agent 、referer 以及client-ip/x-forward-for
- $_FILES变量也不受GPC保护测试代码:
```php
";
echo 'GPC目前的值为 '.get_magic_quotes_gpc();
echo '
client-ip= ' . $_SERVER["HTTP_CLIENT_IP"];
echo '
$_GET[a]= ' . $_GET[a];
?>
```

然后在浏览器中访问:
```
http://localhost/2020CodeAudit/c8/8-1-1-gpc-server.php?a=1'
```
看看发送包:

右键点中这个记录,Send to repeater

添加 http头,发送Send
```
client-ip: a'
```
最后结果显示$_SERVER 中的环境变量并没有进行特殊字符的转义。
## 1.1. 编码转换问题
```php
";
$sql = "where id = '" . urldecode("-1%df%5c' -- ") . "'";
print_r(mb_convert_encoding($sql,"UTF-8","GBK"));//编码转换函数
echo '
';
print_r($sql);
?>
```
```
http://localhost/2020CodeAudit/c8/8-1-2-covert-encode.php
```
结果:
```
mb_convert_encoding函数使用举例:
where id = '-1運' -- '
where id = '-1�\' -- '
```
这就是以前讲的宽字节注入的漏洞,只不过这里使用 mb_convert_encoding 函数把UTF8转码到 GBK 进行模拟。可以看看源文件的编码是UTF8。
书上 144 页有个例子
# 2. 神奇的字符串
## 2.1. 字符处理函数报错信息泄露
- 要显示错误信息需要打开在PHP配置文件 php.ini 中设置 display_errors = on 或者在代码中加入error_reporting()函数
- 其中最常用的是E_ALL、E_WARNING、E_NOTICE
- E_ALL代表提示所有问题, E_WARNING代表显示错误信息,E_NOTICE则是显示基础提示信息。
trim ()函数对用户名等值去掉两边的空格,这时候如果我们传入的用户名参数是一个数组,则程序就会报错,测试代码:
```php
";
echo trim($_GET['a']);//当输入?a[]=test时,程序报错
?>
```
```
http://localhost/2020CodeAudit/c8/8-2-1-trim-error.php?a[]=test
```
结果:
```
利用报错信息举例:
Notice: Array to string conversion in C:\autit\www\2020CodeAudit\C8\8-2-1-trim-error.php on line 6
Array
```
## 2.2. iconv函数字符编码转换截断
- iconv()函数用来做字符编码转换;
- 比如从UTF-8转换到GBK字符集的编码转换总会存在一定的差异性,导致部分编码不能被成功转换,也就是出现常说的乱码。
- 在使用iconv()函数转码的时候,当遇到不能处理的字符串则后续字符串会不被处理
```php
";
//chr() 函数从指定的 ASCII 值返回字符。
/*
ASCII码:
数字 32–126 分配给了能在键盘上找到的字符,当您查看或打印文档时就会出现。注:十进制32代表空格 ,十进制数字 127 代表 DELETE 命令。
ASCII 表上的数字 0–31 分配给了控制字符,用于控制像打印机等一些外围设备
扩展的 ASCII 包含 ASCII 中已有的 128 个字符,又增加了 128 个字符,总共是 256 个。
*/
$a = '1' . chr(130) . '2';
echo $a;
echo '
';
echo iconv("UTF-8","gbk",$a);
?>
```
```
http://localhost/2020CodeAudit/c8/8-2-2-2-iconv.php
```
结果:
```
iconv()函数使用举例:
1�2
1
```
通过这里例子可以看到,转换后的字符串被切断了。149页的漏洞就是利用iconv这个特点,可以上传任意类型的文件。
# 3. [php://输入输出流](https://www.php.net/manual/zh/wrappers.php.php)
- PHP提供了php://的协议允许访问 PHP的输入输出流、标准输入输出和错误描述符
- 内存中、磁盘备份的临时文件流以及可以操作其他读取写入文件资源的过滤器。
151 页:
## 3.1. php://input
- 可以访问请求的原始数据的只读流。
- 即可以直接读取到POST没有经过解析的原始数据, 但是php://input不能以获取“multipart/form-data”方式提交的数据。
```php
";
echo file_get_contents("php://input");
?>
```
```
http://localhost/2020CodeAudit/c8/8-3-phpinput.php
```

前面的例子中可以通过该方式注入PHP代码。
## 3.2. php://output和php://filter
- php://output:将流数据输出
- php://filter是一个文件操作的协议,可以对磁盘中的文件进行读写操作,效果类似 于readfile()、file()和file_get_contents()
| 名 称 | 描 述 |
| ------------------------- | ------------------------------------------------------------ |
| resource=<要过滤的数据流> | 该参数是必须的。它指定了你要筛选过滤的数据流 |
| read=<读链的筛选列表> | 该参数可选,可以设定一个或多个过滤器名称,以管道符(\|) 分隔 |
| write=<写链的筛选列表> | 该参数可选,可以设定一个或多个过滤器名称,以管道符(\|) 分隔 |
| <;两个链的筛选列表> | 任何没有以read=或write=作前缀的筛选器列表会视情况应 用于读或写链 |
### 3.2.1. php://filter写文件
```php
";
//ROT13是一种简易的替换式密码。
file_put_contents("php://filter/write=string.rot13/resource=example.txt","Hello world123");
?>
```
```
http://localhost/2020CodeAudit/c8/8-3-phpfilter-1.php
```
```file_put_contents("php://filter/write=string.rot13/resource=example.txt","Hello world123");```会向脚本同目录下写入“example.txt”文件,内容为rot13编码过的“Hello World123”
```
Uryyb jbeyq123
```
### 3.2.2. php://filter读文件
```php
";
//输入?f=php://filter/convert.base64-encode/resource=1.php
include($_GET['f']);
?>
```
```
http://localhost/2020CodeAudit/c8/8-3-phpfilter-2.php?f=php://filter/convert.base64-encode/resource=1.php
```
结果:
```
php://filter使用举例2:
PD9waHANCglwaHBpbmZvKCk7DQo/Pg==
```
相当于使用 base64 对 1.php 文件进行编码,其结果被包含到输出流中。
如果是:
```
http://localhost/2020CodeAudit/c8/8-3-phpfilter-2.php?f=1.php
```
就会包含1.php中的内容,如果有php代码,就会执行。
# 4. PHP代码解析标签
PHP有几种解析标签的写法来标识PHP代码
- 脚本标签:```-->
<% phpinfo(); %>