从一道CTF的非预期解看PHP反斜杠匹配问题

前言

刷buuoj的时候遇到这样一个题,做一半看到他这个正则写的有点问题,就去翻wp。


image

找到了官方的wp发现果然是个非预期。

image

但是官方wp中并没有深入说明。后来看到评论去翻出题人的博客也没找到相关的信息,加上看到了其他wp中一些不准确的说法,所以今天就有了这篇文章来讲一讲自己的看法。

正文

题目源码

<?php
error_reporting(E_ALL || ~ E_NOTICE);
header('content-type:text/html;charset=utf-8');
$cmd = $_GET['cmd'];
if (!isset($_GET['img']) || !isset($_GET['cmd'])) 
    header('Refresh:0;url=./index.php?img=TXpVek5UTTFNbVUzTURabE5qYz0&cmd=');
$file = hex2bin(base64_decode(base64_decode($_GET['img'])));

$file = preg_replace("/[^a-zA-Z0-9.]+/", "", $file);
if (preg_match("/flag/i", $file)) {
    echo '<img src ="./ctf3.jpeg">';
    die("xixi~ no flag");
} else {
    $txt = base64_encode(file_get_contents($file));
    echo "<img src='data:image/gif;base64," . $txt . "'></img>";
    echo "<br>";
}
echo $cmd;
echo "<br>";
if (preg_match("/ls|bash|tac|nl|more|less|head|wget|tail|vi|cat|od|grep|sed|bzmore|bzless|pcre|paste|diff|file|echo|sh|\'|\"|\`|;|,|\*|\?|\\|\\\\|\n|\t|\r|\xA0|\{|\}|\(|\)|\&[^\d]|@|\||\\$|\[|\]|{|}|\(|\)|-|<|>/i", $cmd)) {
    echo("forbid ~");
    echo "<br>";
} else {
    if ((string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b'])) {
        echo `$cmd`;
    } else {
        echo ("md5 is funny ~");
    }
}

前面md5碰撞已经是老套路了,问题出在后面对shell命令的过滤上。

if (preg_match("/ls|bash|tac|nl|more|less|head|wget|tail|vi|cat|od|grep|sed|bzmore|bzless|pcre|paste|diff|file|echo|sh|\'|\"|\`|;|,|\*|\?|\\|\\\\|\n|\t|\r|\xA0|\{|\}|\(|\)|\&[^\d]|@|\||\\$|\[|\]|{|}|\(|\)|-|<|>/i", $cmd)) {
    echo("forbid ~");
    echo "<br>";
} 

熟悉php代码审计的同学应该都知道,在preg_match中要过滤\ 是需要四个\\\\才可以达到目的,原理如下:

$str = '\/div';
$pattern = '/\\\\\/div/';
// '\\\\\/' 解析过程如下:
// PHP解析:
// 第1个'\'转义第2个'\',转义后为字符串'\'
// 第3个'\'转义第4个'\',转义后为字符串'\'
// 第5个'\'转义'/',转义后为字符串'/'
// 字符合起来为'\\/' (则 \\/div 即为正则将要解析的内容,注意:正则解析的内容已经不包括正则标识符//)
// 正则解析器解析:
// 两个'\\' 正则表达式看做'\' (则正则最终解析为 \/div)
$rs = preg_match($pattern, $str, $arr);
if($rs) print_r($arr); // Array ( [0] => \/div )

但是出题人似乎觉得不够,又在后面加了四个反斜杠的匹配,似乎本意是要过滤\\\

理论来说已经出现了四个\\\\了,但是为什么还会造成非预期ca\t这种解呢?

我们本地测试一下

去掉其他的乱七八糟的东西,只留下对于反斜杠等的过滤

image

可以看到虽然正则中有\\\\,但是却无法过滤到反斜杠。

反向思考其原因,应该是问题出在前面两个反斜杠的匹配部分。

因为正则匹配中相当于要经过两层解析器解析,一层是php的,一层是正则表达式的。所以此处前面的两个反斜杠经过php解析器处理后应该是表示了一个转义号\,之后又与后面的表示逻辑或的|结合到一起,从而在正则表达式解析器中解析为\|。又因为|是正则中的保留符号,所以需要一个转义符来转义。所以最后的实现效果应为对于字符|的过滤。

所以我们猜测这种写法真正被解析的结果应该是对于字符串|\的过滤,即不是单独的\的匹配。

我们来验证一下猜想是否正确:


image

可以看到此时已经触发了正则匹配机制,输出了forbid。

所以综上所述:非预期的原因是错误的正则写法匹配了|\,而非预期的\

错误的一些说法

第一个

https://www.cnblogs.com/20175211lyz/p/12189515.html
这篇文章中提到反斜杠有这么多种匹配方法,如果你做实验的话发现也确实会输出1234。事实真的是这样吗?

image

随便写个字符串,发现134照样可以匹配到。

image

原因是134条规则都在左右多加了个|,然而|左右为空,也就是说对于任意空字符串都可以匹配,而并非预期的目的。

第二个

这篇文章的解释是把\t当成tab,这个就更离谱了。
https://blog.csdn.net/SopRomeo/article/details/104124545

image

第三个

https://www.jianshu.com/p/21e3e1f74c08

image

这个同学自己调试了一番,离真相就差一点啦。

最后

纸上得来终觉浅,绝知此事要躬行。

与君共勉。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 151,511评论 1 330
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 64,495评论 1 273
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 101,595评论 0 225
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 42,558评论 0 190
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 50,715评论 3 270
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 39,672评论 1 192
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,112评论 2 291
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,837评论 0 181
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,417评论 0 228
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,928评论 2 232
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,316评论 1 242
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,773评论 2 234
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,253评论 3 220
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,827评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,440评论 0 180
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 34,523评论 2 249
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 34,583评论 2 249

推荐阅读更多精彩内容