前言

之前在攻防世界上随便做了个题,发现了这个陌生的preg_replace函数\e情况下的漏洞。像我这种对这陌生的小白来说第一次理解是比较困难的。花了两天时间看了许多师傅的文章,这才理解。为此写下这篇文章总结一下,也希望后上路的小伙伴能看了我的文章能有所收获。

preg_replace函数

这个php函数是通过正则替换用的,基本形式为

mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject )
preg_replace(正则表达式;替换成什么东西;目标字符串)

举个例子更容易理解

<?php
$str = "wo shi da shuai ge";
echo $str;
echo "\n";
$ste = preg_replace('/shi/','bu shi',$str);
echo $ste;
?>

这个代码就是在str字符串中搜索"shi"这个字符串,然后将它替换为"bu shi";看运行结果:

wo shi da shuai ge
wo bu shi da shuai ge

preg_replace函数中\e模式下的漏洞

在pattern参数后添加\e,可以使replacement参数中的字符串可当做php代码执行。

下面主要用一个案例主要来说明一下

<?phpfunction complex($re, $str) {return preg_replace('/(' . $re . ')/ei','strtolower("\\1")',$str);
}foreach($_GET as $re => $str) {echo complex($re, $str). "\n";
}function getFlag(){@eval($_GET['cmd']);
}

这是buu上一道典型的preg_replace命令执行漏洞。

首先审计代码,定义两个函数complex和geyFlag。complex函数返回一个被正则替换后的字符串,getFlag函数中存在eval命令执行。那么\1是什么?

反向引用

这是我当时比较难理解的地方,在了解这个之前,先来了解一下什么是捕获组。形式为(),匹配的是()中的字符。取匹配结果的时候,括号中的表达式匹配到的内容可以被单独得到。每一对括号会分配一个编号,使用()的捕获从左括号的顺序从1开始自动编号。 每一对括号就会分配一个编号,反向引用就是对已捕获的字符串进引用。

()的使用1.()表示分组,顺序从外到里,从左到右。
2.分组从1开始,0默认代表全部匹配的文本。
3.例如(a(b))
4.分组1:(a(b))    分组2: (b)

反向引用的使用:\1 \2等。

\1:表示的是引用第一次匹配到的()括起来的部分

\2:表示的是引用第二次匹配到的()括起来的部分

例如:string regx="(\\d)\\1";
此正则会匹配上重复字符比如11,22,33,44等,因为(\\d)会先去匹配一个字符,然后\1对一个分组进行引用,意思是再引用前面(\\d)捕获的数字。又例如:string regx="^(\\d)\\1[0-9](\d)\1{2}";
此正则可以匹配114511;116511;227622;

简单讲解一个第二个例子。

画图能力不太行,望各位师傅见谅。总而言之,就是末尾的\1依然是引用前面(\\d)捕获的数字。想了解更多反向引用的知识,看这篇师傅的文章正则基础之——反向引用 - 石 磊 - 博客园

构造payload

回看代码,strtolower函数就是把字符串转换为小写,其他数字字符保持不变。foreach是一个数组遍历的函数,在此不多说。可以看到preg_replace函数中有\e, 那么strtolower("\\1");会被当作php代码执行,但是这个字符串无法被修改,那该怎么进行命令执行呢?

那么我们就要用到\1来引用第一个捕获组捕获的字符。先构造payload:

/?.*=${执行的命令}

构造前

preg_replace('/(' . $re . ')/ei','strtolower("\\1")',$str);

构造后

preg_replace('/(.*)/ei','strtolower("\\1")',${执行的命令});

$re=.*    $str=${执行的命令}

那为什么要这么构造payload?  细看这个函数,(.*)为一个捕获组,它要匹配$str中的字符串,而.*匹配所有字符,即捕获组内的内容就是$str内的字符串,\1再对捕获组中字符串的引用,就可以间接命令执行了(个人理解,如有不对,欢迎各位师傅指正)。基本构造payload思路大概就是这样。

小知识点

上面那个payload其实是不可行的,因为上面$re参数是由Get方式传入,如果有以非法字符开头的参数,就会自动将非法字符转换为下划线(POST传参不会),会导致匹配失败,所以不可行。我们知道,\s是匹配任何空白非打印字符,包括空格,字符表,换页符等等,而\S是打印任何非空白字符,所以我们可以用\S来代替.

那为什么要用{}进行包裹。因为在PHP中,双引号是可以解析变量的,但是单引号不行,使用大括号就可以有效的解决这个问题,例如${phpinfo()}中的phpinfo()会被当作变量先执行,执行后就变成${1}(因为phpinfo函数执行成功后会返回true,即返回1)。

总结

此案例的重点就是反向引用。通过preg_replace中\e模式下的漏洞,构造正则表达式,可以达到远程命令执行的效果。

preg_replace与远程代码执行相关推荐

  1. thinkphp5+远程代码执行_ThinkPHP5 5.0.23 远程代码执行漏洞

     漏洞描述 ThinkPHP是一款运用极广的PHP开发框架.其5.0.23以前的版本中,获取method的方法中没有正确处理方法名,导致攻击者可以调用Request类任意方法并构造利用链,从而导致远程 ...

  2. linux内核远程漏洞,CVE-2019-11815:Linux内核竞争条件漏洞导致远程代码执行

    *本文中涉及到的相关漏洞已报送厂商并得到修复,本文仅限技术研究与讨论,严禁用于非法用途,否则产生的一切后果自行承担. 运行了Linux发行版的计算机设备,如果内核版本小于5.0.8的话,将有可能受到一 ...

  3. ElasticSearch Groovy脚本远程代码执行漏洞

    什么是ElasticSearch? 它是一种分布式的.实时性的.由JAVA开发的搜索和分析引擎. 2014年,曾经被曝出过一个远程代码执行漏洞(CVE-2014-3120),漏洞出现在脚本查询模块,由 ...

  4. Linux包管理器apt/apt-get发现远程代码执行漏洞

    研究人员Max Justicz日前发现了知名Linux包管理器apt/apt-get中的远程代码执行漏洞,该漏洞允许外部进行中间人攻击并获取root权限以执行任何代码.该漏洞已在最新版本apt修复,如 ...

  5. filter执行先后问题_Thinkphp5框架变量覆盖导致远程代码执行

    Thinkphp5.0.x框架对输入数据过滤不严,导致Request类成员存在变量覆盖问题,在一定情况下能导致远程代码执行漏洞. 介绍 Thinkphp框架官方提供核心版和完整版两种: 核心版因默认缺 ...

  6. wordpress php执行短代码_【漏洞通告】PHP远程代码执行漏洞(CVE-2019-11043)

    1.综述2019年9月14日至18举办的 Real World CTF中,国外安全研究员 Andrew Danau 在解决一道CTF题目时发现,向目标服务器 URL 发送 %0a 符号时,服务返回异常 ...

  7. c++ 界面交互影响处理代码执行速度_原创 | 某SCADA的远程代码执行漏洞挖掘与利用...

    作者 | 绿盟科技格物实验室 陈杰 前言 近年来网络安全形势日渐严峻,国内外都开始对工控安全越来越重视,而工控领域由于常年来对安全的忽视,导致暴露出数量惊人的严重安全漏洞,更为严重的是,相当一部分厂商 ...

  8. ImageMagick远程代码执行漏洞CVE-2016-8707 绿盟科技发布安全威胁通告

    在 ImageMagicks 的转换实用程序中, TIFF 图像压缩处理存在一个写边界的问题.攻击者利用一个精心编制的 TIFF 文件,可以导致的界限写,特别是可以利用的情况下进入远程执行代码.任何用 ...

  9. Source引擎的远程代码执行漏洞,可能影响千万游戏玩家

    本文讲的是Source引擎的远程代码执行漏洞,可能影响千万游戏玩家, 目前多款主流游戏,如CS.绝地要塞等都在使用Source引擎,Source引擎由Valve软件公司开发,这个引擎提供关于渲染.声效 ...

最新文章

  1. 使用iframe call server及iframe target使用例
  2. Android开发之2048安卓版
  3. Java多线程--synchronized修饰普通方法和修饰静态方法的区别
  4. ITK:Delaunay贴合边缘翻转
  5. JAVA自学笔记22
  6. ZeroMq的研究和使用
  7. 电脑一族,打电脑时候的健康的坐姿
  8. 土拍熔断意味着什么_火爆!楼面价14615元/㎡,土拍过后房价涨,常州买房正当时!...
  9. 2014年百度之星程序设计大赛 - 初赛(第二轮)JZP Set
  10. linux命令界面输入不了密码,如何在 Linux 中不输入密码运行 sudo 命令
  11. linux系统支持速达软件吗,速达3000系列常见问题100问
  12. 14152学年C#程序设计语言与.Net框架基础课程之学生blog名单
  13. 如何修改IDM下载器的临时文件夹位置
  14. Ubuntu18设置4K屏幕缩放125%
  15. 华为p10计算机器在哪,华为P10怎么连接电脑教程
  16. Java web框架
  17. 微信公众号开发002-微信网页授权
  18. Ubuntu16.04搜索不到wifi
  19. mac服务器文件同步软件,[MACOS]使用fswatch和SCP配合实现自动单向实时同步文件
  20. Whale帷幄 - 车企数字化营销转型

热门文章

  1. 27、火灾危险性分类
  2. vue在微信里面的兼容问题_Vue在 iOS 微信浏览器下不能播放
  3. TYPE-C接口安卓手机直播快充领夹式无线麦克风方案
  4. 人人美剧迅雷链接多线程和多进程爬虫分析
  5. 微信小程序云开发CMS中WebHook功能的使用方法
  6. licode的ios最新版本的接入
  7. 网络安全笔记-TCP/IP
  8. 推荐一个动画框架Lottie
  9. centos7 离线升级/在线升级操作系统内核
  10. 黑马程序员MySQL视频操作代码-P79