自用2024.11.26——[ACTF2020 新生赛]Include 1

一、解题步骤

  1. 查看源代码+抓包,没发现有用信息

  2. 查看题目和网址的file参数,提示这是文件包含的题。

  3. 构造payload

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

  4. 读出源码,进行base64解码得出flag

解码结果为

可知flag是被注释掉了的,所以需要进行编码再解码,将其翻译出来

二、解析payload

  1. 解析payload——php://filter协议

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

php://filter 是格式

read= 是可选参数,有read和write,即读和写。若此处为空,那么网页会自动匹配一个合适的read或write

则payload为

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

convert.base64-encode过滤器。主要有四种:字符串过滤器转换过滤器压缩过滤器加密过滤器。filter里可以用一或多个过滤器(中间用 | 隔开)。此处是指把文件 flag.php 里的代码转换(convert)为base64编码(encode)

举例:大写转换过滤器: string.toupper

resource= 是必选参数,后面是要处理的文件名

三、php://filter的使用

还可以用于绕过,即将不希望执行的语句先编码,这个编码类型可以破坏语句的正常执行(如base64编码只有64个字符,如果被编码的语句字符在64个字符里找不到对应的,就会忽略然后继续编码),之后再解码,就可以绕过语句了。

四、php伪协议

PHP伪协议主要用于在PHP环境下提供特殊的输入/输出方式。

它可以让开发者在代码中像访问本地文件一样读取其他数据,例如读取PHP文件的源代码。也能用于包含远程文件,在特定场景下实现代码复用,但这也可能带来安全风险,如被攻击者恶意利用包含远程恶意脚本。此外,在测试环境下,通过伪协议可以方便地模拟数据输入,用于调试程序等。

php支持的伪协议

    1 file:// — 访问本地文件系统
    2 http:// — 访问 HTTP(s) 网址
    3 ftp:// — 访问 FTP(s) URLs
    4 php:// — 访问各个输入/输出流(I/O streams)
    5 zlib:// — 压缩流
    6 data:// — 数据(RFC 2397)
    7 glob:// — 查找匹配的文件路径模式
    8 phar:// — PHP 归档
    9 ssh2:// — Secure Shell 2
    10 rar:// — RAR
    11 ogg:// — 音频流
    12 expect:// — 处理交互式的流

1.php://filter简介

是一种元封装器,设计用于数据流打开时的筛选过滤应用。这对于一体式(all-in-one)的文件函数非常有用,类似readfile()、file()和file_get_contents(),在数据流内容读取之前没有机会应用其他过滤器。

简单来说:这是一个中间件,在读入或写入数据的时候对数据进行处理后输出的一个过程。

php://filter可以获取指定文件源码。当它与包含函数结合时,php://filter流会被当作php文件执行。从而导致任意文件读取。

协议参数

名称 描述
resource=<要过滤的数据流> 这个参数是必须的。它指定了你要筛选过滤的数据流。
read=<读链的筛选列表> 该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。
write=<写链的筛选列表> 该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。
<;两个链的筛选列表> 任何没有以 read= 或 write= 作前缀 的筛选器列表会视情况应用于读或写链。

2.过滤器

①字符串过滤器

该类通常以string开头,对每个字符都进行同样方式的处理。

string.rot13:一种字符处理方式,字符右移十三位。

string.toupper :将所有字符转换为大写。

string.tolower :将所有字符转换为小写。

string.strip_tags :用来处理掉读入的所有标签,例如XML的等等。在绕过死亡exit大有用处。

②对数据流进行编码,通常用来读取文件源码。

convert.base64-encode & convert.base64-decode :base64加密&解密

convert.quoted-printable-encode & convert.quoted-printable-decode :翻译为可打印字符引用编码&使用可以打印的ASCII编码的字符表示各种编码形式下的字符。

③压缩过滤器

注意,这里的压缩过滤器指的并不是在数据流传入的时候对整个数据进行写入文件后压缩文件,也不代表可以压缩或者解压数据流。压缩过滤器不产生命令行工具如 gzip 的头和尾信息。只是压缩和解压数据流中的有效载荷部分。

注:gzip用于压缩文件,生成 .gz 后缀的压缩文件。

用到的两个相关过滤器:zlib.deflate(压缩)和 zlib.inflate(解压)。zilb是比较主流的用法,至于bzip2.compressbzip2.decompress工作的方式与 zlib 过滤器大致相同。

④加密过滤器

mcrypt.*mdecrypt.*使用 libmcrypt 提供了对称的加密和解密。

更多妙用:谈一谈php://filter的妙用 | 离别歌

3.利用filter伪协议绕过死亡exit

①什么是死亡exit

在C语言中,exit函数是一个标准库函数,用于正常终止程序的执行。这个函数定义在 头文件中。当程序执行到 “exit” 函数时,会立即结束程序的运行,并且可以返回一个状态码给操作系统或调用该程序的父进程等,以表示程序结束时的某种状态(比如正常结束返回 0,出现错误按约定返回特定的非零值等)。

此时,即使插入一句话木马,也无法被执行。如:

这样的死亡exit通常存在于缓存、配置文件等等不允许用户直接访问的文件当中。

②绕过
<1>base64decode绕过

利用filter协议来绕过,如下代码:

';
​
$content .= $_POST['txt'];
​
file_put_contents($_POST['filename'], $content);

当用户通过POST方式提交一个数据时,会与死亡exit进行拼接,从而避免提交的数据被执行。

然而这里可以利用php://filter的base64-decode方法,将¥content解码,利用php base64_decode函数特性去除死亡exit。

base64编码中只包含64个可打印字符,当PHP遇到不可解码的字符时,会选择性的跳过,这个时候base64就相当于以下的过程:

所以,当$content 包含 时,解码过程会先去除识别不了的字符,< ; ? >和空格等都将被去除,于是剩下的字符就只有phpexit以及我们传入的字符了。由于base64是4个byte一组,再添加一个字符例如添加字符’a’后,将’phpexita’当做两组base64进行解码,也就绕过这个死亡exit了。

这个时候后面再加上编码后的一句话木马,就可以getshell了。

<2>strip_tags绕过

(1)strip_tags函数:剥去字符串中的HTML、XML以及PHP的标签。

(2)XML:可拓展标记语言。主要用来描述数据。

(3)这个实际上是一个XML标签,既然是XML标签,我们就可以利用strip_tags函数去除它,而php://filter刚好是支持这个方法的。

但是我们要写入的一句话木马也是XML标签,在用到strip_tags时也会被去除。

注意到在写入文件的时候,filter是支持多个过滤器的。可以先将webshell经过base64编码,strip_tags去除死亡exit之后,再通过base64-decode复原。如:

php://filter/string.strip_tags|convert.base64-decode/resource=shell.php

2.data://

数据流封装器,以传递相应格式的数据。可以让用户来控制输入流,当它与包含函数结合时,用户输入的data://流会被当作php文件执行。

3.file://

用于访问本地文件系统,并且不受allow_url_fopen,allow_url_include影响。

file://协议主要用于访问文件(绝对路径、相对路径以及网络路径)。比如:http://www.xx.com?file=file:///etc/passsword

4 php://

在allow_url_fopen,allow_url_include都关闭的情况下可以正常使用 php://作用为访问输入输出流

5 php://input

php://input可以访问请求的原始数据的只读流,将post请求的数据当作php代码执行。

当传入的参数作为文件名打开时,可以将参数设为php://input,同时post想设置的文件内容,php执行时会将post内容当作文件内容。从而导致任意代码执行

例如:

http://127.0.0.1/cmd.php?cmd=php://input

POST数据:

注意:

  • 当enctype="multipart/form-data"的时候 php://input` 是无效的

  • 遇到file_get_contents()要想到用php://input绕过。

6 zip://

zip:// 可以访问压缩包里面的文件。当它与包含函数结合时,zip://流会被当作php文件执行。从而实现任意代码执行。

  • zip://中只能传入绝对路径。

  • 要用#分隔压缩包和压缩包里的内容,并且#要用url编码%23(即下述POC中#要用%23替换)

  • 只需要是zip的压缩包即可,后缀名可以任意更改。

  • 相同的类型的还有zlib://和bzip2://

POC
zip://[压缩包绝对路径]#[压缩包内文件]
如:?file=zip://D:\zip.jpg%23phpinfo.txt

你可能感兴趣的:(android)